Coverage for RO-VIM-openstack/osm_rovim_openstack/tests/test_vimconn_openstack.py: 99%
3160 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-14 12:04 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-04-14 12:04 +0000
1# -*- coding: utf-8 -*-
3##
4# Copyright 2017 Intel Corporation.
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#
18# For those usages not covered by the Apache License, Version 2.0 please
19# contact with: nfvlabs@tid.es
20##
22"""
23This module contains unit tests for the OpenStack VIM connector
24Run this directly with python2 or python3.
25"""
26from copy import deepcopy
27import logging
28import unittest
30import cinderclient.exceptions as cExceptions
31from mock import MagicMock, patch
32from neutronclient.common import exceptions as neExceptions
33from novaclient import exceptions as nvExceptions
34from novaclient.exceptions import ClientException, Conflict
35from osm_ro_plugin.vimconn import (
36 VimConnConnectionException,
37 VimConnException,
38 VimConnNotFoundException,
39 VimConnUnexpectedResponse,
40)
41from osm_rovim_openstack.vimconn_openstack import vimconnector
42from requests.exceptions import ConnectionError
44__author__ = "Igor D.C."
45__date__ = "$23-aug-2017 23:59:59$"
47# Variables Used in TestNewVmInstance Class
48name = "basicvm"
49description = "my firewall"
50start = True
51image_id = "408b73-e9cc-5a6a-t270-82cc4811bd4a"
52flavor_id = "208b73-e9cc-5a6a-t270-82cc4811bd4a"
53affinity_group_list = []
54net_list = []
55cloud_config = {}
56disk_list = []
57disk_list2 = [
58 {"size": 10, "image_id": image_id},
59 {"size": 20},
60]
61availability_zone_index = 0
62availability_zone_list = ["nova"]
63security_group_name = None
64floating_network_vim_id = "108b73-e9cc-5a6a-t270-82cc4811bd4a"
65net_id = "83372685-f67f-49fd-8722-eabb7692fc22"
66net2_id = "46472685-f67f-49fd-8722-eabb7692fc22"
67mac_address = "00:00:5e:00:53:af"
68port_id = "03372685-f67f-49fd-8722-eabb7692fc22"
69time_return_value = 156570000
70port2_id = "17472685-f67f-49fd-8722-eabb7692fc22"
71root_vol_id = "tc408b73-r9cc-5a6a-a270-82cc4811bd4a"
72ip_addr1 = "20.3.4.5"
73volume_id = "ac408b73-b9cc-4a6a-a270-82cc4811bd4a"
74volume_id2 = "o4e0e83-b9uu-4akk-a234-89cc4811bd4a"
75volume_id3 = "44e0e83-t9uu-4akk-a234-p9cc4811bd4a"
76volume_id4 = "91bf5674-5b85-41d1-aa3b-4848e2691088"
77virtual_mac_id = "64e0e83-t9uu-4akk-a234-p9cc4811bd4a"
78created_items_all_true = {
79 f"floating_ip:{floating_network_vim_id}": True,
80 f"volume:{volume_id}": True,
81 f"port:{port_id}": True,
82}
85# Variables used in TestNewFlavor Class
86name1 = "sample-flavor"
87extended = (
88 {
89 "cpu-quota": {"limit": 3},
90 "mem-quota": {"limit": 1},
91 "mempage-size": "LARGE",
92 "cpu-pinning-policy": "DEDICATED",
93 "mem-policy": "STRICT",
94 },
95)
96flavor_data = {
97 "name": name1,
98 "ram": 3,
99 "vcpus": 8,
100 "disk": 50,
101 "extended": extended,
102}
104flavor_data2 = {
105 "name": name1,
106 "ram": 3,
107 "vcpus": 8,
108 "disk": 50,
109}
112def check_if_assert_not_called(mocks: list):
113 for mocking in mocks:
114 mocking.assert_not_called()
117class Volume:
118 def __init__(self, s, type="__DEFAULT__", name="", id=""):
119 self.status = s
120 self.volume_type = type
121 self.name = name
122 self.id = id
125class Server:
126 def __init__(self, name="", status="", flavor="", id=""):
127 self.id = id
128 self.name = name
129 self.status = status
130 self.flavor = flavor
133class CopyingMock(MagicMock):
134 def __call__(self, *args, **kwargs):
135 args = deepcopy(args)
136 kwargs = deepcopy(kwargs)
137 return super(CopyingMock, self).__call__(*args, **kwargs)
140class TestNewVmInstance(unittest.TestCase):
141 @patch("logging.getLogger", autospec=True)
142 def setUp(self, mock_logger):
143 # Instantiate dummy VIM connector so we can test it
144 # It throws exception because of dummy parameters,
145 # We are disabling the logging of exception not to print them to console.
146 mock_logger = logging.getLogger()
147 mock_logger.disabled = True
148 self.vimconn = vimconnector(
149 "123",
150 "openstackvim",
151 "456",
152 "789",
153 "http://dummy.url",
154 None,
155 "user",
156 "pass",
157 )
158 self.vimconn.neutron = CopyingMock()
159 self.vimconn.nova = CopyingMock()
160 self.vimconn.cinder = CopyingMock()
161 self.server = MagicMock(object, autospec=True)
162 self.server.tenant_id = "408b73-r9cc-5a6a-a270-82cc4811bd4a"
163 self.server.id = "908b73-e9cc-5a6a-t270-82cc4811bd4a"
164 self.vimconn.config["security_groups"] = "default"
165 self.vimconn.config["keypair"] = "my_keypair"
166 self.vimconn.security_groups_id = "12345"
167 self.vimconn.nova.api_version.get_string.return_value = "2.32"
168 self.vimconn.logger = CopyingMock()
170 @patch.object(vimconnector, "_get_ids_from_name")
171 def test_prepare_port_dict_security_security_groups_exists_in_config(
172 self, mock_get_ids
173 ):
174 """In VIM config security_groups exists, net port_security is True
175 no_port_security_extension does not exist.
176 """
177 self.vimconn.config = {"security_groups": "example_security_group"}
178 net = {"port_security": True}
179 port_dict = {}
180 result_dict = {"security_groups": "12345"}
182 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
183 self.assertDictEqual(result_dict, port_dict)
184 mock_get_ids.assert_not_called()
186 @patch.object(vimconnector, "_get_ids_from_name")
187 def test_prepare_port_dict_security_security_groups_exists_in_config_no_security_groups_id(
188 self, mock_get_ids
189 ):
190 """In VIM config Security_groups exists, net port_security is True, vim security_groups_id does not exist,
191 no_port_security_extension does not exist.
192 """
193 self.vimconn.config = {"security_groups": "example_security_group"}
194 self.vimconn.security_groups_id = None
195 net = {"port_security": True}
196 port_dict = {}
197 result_dict = {"security_groups": None}
199 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
200 self.assertDictEqual(result_dict, port_dict)
201 mock_get_ids.assert_called()
203 @patch.object(vimconnector, "_get_ids_from_name")
204 def test_prepare_port_dict_security_security_groups_exists_security_extension_true_in_config(
205 self, mock_get_ids
206 ):
207 """In VIM config security_groups exists, net port_security is True, in VIM security_groups_id exists,
208 no_port_security_extension set to True.
209 """
210 self.vimconn.config = {
211 "security_groups": "example_security_group",
212 "no_port_security_extension": True,
213 }
214 net = {"port_security": True}
215 port_dict = {}
216 result_dict = {}
218 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
219 self.assertDictEqual(result_dict, port_dict)
220 mock_get_ids.assert_not_called()
222 @patch.object(vimconnector, "_get_ids_from_name")
223 def test_prepare_port_dict_security_no_security_groups_in_config(
224 self, mock_get_ids
225 ):
226 """In VIM config security_group does not exist, net port_security True, in VIM security_groups_id exists,
227 no_port_security_extension does not exist."""
228 self.vimconn.config = {}
229 net = {"port_security": True}
230 port_dict = {}
231 result_dict = {}
233 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
234 self.assertDictEqual(result_dict, port_dict)
235 mock_get_ids.assert_not_called()
237 @patch.object(vimconnector, "_get_ids_from_name")
238 def test_prepare_port_dict_security_no_security_groups_security_extension_true_in_config(
239 self, mock_get_ids
240 ):
241 """Security_group does not exist, net port_security is True, in VIM security_groups_id exists,
242 no_port_security_extension set to True."""
243 self.vimconn.config = {"no_port_security_extension": True}
244 net = {"port_security": True}
245 port_dict = {}
246 result_dict = {}
248 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
249 self.assertDictEqual(result_dict, port_dict)
250 mock_get_ids.assert_not_called()
252 @patch.object(vimconnector, "_get_ids_from_name")
253 def test_prepare_port_dict_security_security_groups_exists_net_port_security_false(
254 self, mock_get_ids
255 ):
256 """In VIM config security_group exists, net port_security False, security_groups_id exists,
257 no_port_security_extension does not exist."""
258 self.vimconn.config = {"security_groups": "example_security_group"}
259 net = {"port_security": False}
260 port_dict = {}
261 result_dict = {}
263 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
264 self.assertDictEqual(result_dict, port_dict)
265 mock_get_ids.assert_not_called()
267 @patch.object(vimconnector, "_get_ids_from_name")
268 def test_prepare_port_dict_security_net_port_security_false_port_security_extension_true(
269 self, mock_get_ids
270 ):
271 """In VIM config security_group exists, net port_security False, security_groups_id exists,
272 no_port_security_extension set to True."""
273 self.vimconn.config = {
274 "security_groups": "example_security_group",
275 "no_port_security_extension": True,
276 }
277 net = {"port_security": False}
278 port_dict = {}
279 result_dict = {}
281 self.vimconn._prepare_port_dict_security_groups(net, port_dict)
282 self.assertDictEqual(result_dict, port_dict)
283 mock_get_ids.assert_not_called()
285 def test_prepare_port_dict_binding_net_type_virtual(self):
286 """net type is virtual."""
287 net = {"type": "virtual"}
288 port_dict = {}
289 result_dict = {}
290 self.vimconn._prepare_port_dict_binding(net, port_dict)
291 self.assertDictEqual(result_dict, port_dict)
293 def test_prepare_port_dict_binding_net_type_vf(self):
294 """net type is VF, vim_type is not VIO."""
295 net = {"type": "VF"}
296 self.vimconn.vim_type = None
297 port_dict = {}
298 result_dict = {"binding:vnic_type": "direct"}
299 self.vimconn._prepare_port_dict_binding(net, port_dict)
300 self.assertDictEqual(port_dict, result_dict)
302 def test_prepare_port_dict_binding_net_type_sriov_vim_type_vio(self):
303 """net type is SR-IOV, vim_type is VIO."""
304 net = {"type": "SR-IOV"}
305 self.vimconn.vim_type = "VIO"
306 port_dict = {}
307 result_dict = {
308 "binding:vnic_type": "direct",
309 "port_security_enabled": False,
310 "provider_security_groups": [],
311 "security_groups": [],
312 }
313 self.vimconn._prepare_port_dict_binding(net, port_dict)
314 self.assertDictEqual(port_dict, result_dict)
316 def test_prepare_port_dict_binding_net_type_passthrough(self):
317 """net type is pci-passthrough."""
318 net = {"type": "PCI-PASSTHROUGH"}
319 port_dict = {}
320 result_dict = {
321 "binding:vnic_type": "direct-physical",
322 }
323 self.vimconn._prepare_port_dict_binding(net, port_dict)
324 self.assertDictEqual(port_dict, result_dict)
326 def test_prepare_port_dict_binding_no_net_type(self):
327 """net type is missing."""
328 net = {}
329 port_dict = {}
330 with self.assertRaises(VimConnException) as err:
331 self.vimconn._prepare_port_dict_binding(net, port_dict)
332 self.assertEqual(str(err.exception), "Type is missing in the network details.")
334 def test_set_fixed_ip(self):
335 """new_port has fixed ip."""
336 net = {}
337 new_port = {
338 "port": {
339 "fixed_ips": [{"ip_address": "10.1.2.3"}, {"ip_address": "20.1.2.3"}]
340 }
341 }
342 result = {"ip": "10.1.2.3"}
343 self.vimconn._set_fixed_ip(new_port, net)
344 self.assertDictEqual(net, result)
346 def test_set_fixed_ip_no_fixed_ip(self):
347 """new_port does not have fixed ip."""
348 net = {}
349 new_port = {"port": {}}
350 result = {"ip": None}
351 self.vimconn._set_fixed_ip(new_port, net)
352 self.assertDictEqual(net, result)
354 def test_set_fixed_ip_raise_exception(self):
355 """new_port does not have port details."""
356 net = {}
357 new_port = {}
358 with self.assertRaises(Exception) as err:
359 self.vimconn._set_fixed_ip(new_port, net)
360 self.assertEqual(type(err.exception), KeyError)
362 def test_prepare_port_dict_mac_ip_addr(self):
363 """mac address and ip address exist."""
364 net = {
365 "mac_address": mac_address,
366 "ip_address": "10.0.1.5",
367 }
368 port_dict = {}
369 result_dict = {
370 "mac_address": mac_address,
371 "fixed_ips": [{"ip_address": "10.0.1.5"}],
372 }
373 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
374 self.assertDictEqual(port_dict, result_dict)
376 def test_prepare_port_dict_mac_ip_addr_empty_net(self):
377 """mac address and ip address does not exist."""
378 net = {}
379 port_dict = {}
380 result_dict = {}
381 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
382 self.assertDictEqual(port_dict, result_dict)
384 def test_prepare_port_dict_mac_ip_addr_dual(self):
385 """mac address, ipv4 and ipv6 addresses exist."""
386 net = {
387 "mac_address": mac_address,
388 "ip_address": ["10.0.1.5", "2345:0425:2CA1:0000:0000:0567:5673:23b5"],
389 }
390 port_dict = {}
391 result_dict = {
392 "mac_address": mac_address,
393 "fixed_ips": [
394 {"ip_address": "10.0.1.5"},
395 {"ip_address": "2345:0425:2CA1:0000:0000:0567:5673:23b5"},
396 ],
397 }
398 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
399 self.assertDictEqual(port_dict, result_dict)
401 def test_prepare_port_dict_mac_ip_addr_dual_ip_addr_is_not_list(self):
402 """mac address, ipv4 and ipv6 addresses exist."""
403 net = {
404 "mac_address": mac_address,
405 "ip_address": "10.0.1.5",
406 }
407 port_dict = {}
408 result_dict = {
409 "mac_address": mac_address,
410 "fixed_ips": [
411 {"ip_address": "10.0.1.5"},
412 ],
413 }
414 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
415 self.assertDictEqual(port_dict, result_dict)
417 def test_prepare_port_dict_mac_ip_addr_dual_net_without_ip_addr(self):
418 """mac address, ipv4 and ipv6 addresses exist."""
419 net = {
420 "mac_address": mac_address,
421 "ip_address": [],
422 }
423 port_dict = {}
424 result_dict = {
425 "mac_address": mac_address,
426 }
427 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
428 self.assertDictEqual(port_dict, result_dict)
430 def test_prepare_port_dict_mac_ip_addr_dual_net_without_mac_addr(self):
431 """mac address, ipv4 and ipv6 addresses exist."""
432 net = {
433 "ip_address": ["10.0.1.5", "2345:0425:2CA1:0000:0000:0567:5673:23b5"],
434 }
435 port_dict = {}
436 result_dict = {
437 "fixed_ips": [
438 {"ip_address": "10.0.1.5"},
439 {"ip_address": "2345:0425:2CA1:0000:0000:0567:5673:23b5"},
440 ],
441 }
442 self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
443 self.assertDictEqual(port_dict, result_dict)
445 def test_create_new_port(self):
446 """new port has id and mac address."""
447 new_port = {
448 "port": {
449 "id": port_id,
450 "mac_address": mac_address,
451 },
452 }
453 self.vimconn.neutron.create_port.return_value = new_port
454 net, port_dict, created_items = {}, {}, {}
455 expected_result = new_port
456 expected_net = {
457 "mac_address": mac_address,
458 "vim_id": port_id,
459 }
460 expected_created_items = {f"port:{port_id}": True}
461 result = self.vimconn._create_new_port(port_dict, created_items, net)
462 self.assertDictEqual(result, expected_result)
463 self.assertEqual(net, expected_net)
464 self.assertEqual(created_items, expected_created_items)
465 self.vimconn.neutron.create_port.assert_called_once_with({"port": port_dict})
467 def test_create_new_port_without_mac_or_id(self):
468 """new port does not have mac address or ID."""
469 new_port = {}
470 self.vimconn.neutron.create_port.return_value = new_port
471 net, port_dict, created_items = {}, {}, {}
472 with self.assertRaises(KeyError):
473 self.vimconn._create_new_port(port_dict, created_items, net)
474 self.vimconn.neutron.create_port.assert_called_once_with({"port": port_dict})
476 def test_create_new_port_neutron_create_port_raises_exception(self):
477 """Neutron create port raises exception."""
478 self.vimconn.neutron.create_port.side_effect = VimConnException(
479 "New port is not created."
480 )
481 net, port_dict, created_items = {}, {}, {}
482 with self.assertRaises(VimConnException):
483 self.vimconn._create_new_port(port_dict, created_items, net)
484 self.vimconn.neutron.create_port.assert_called_once_with({"port": port_dict})
486 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
487 @patch.object(vimconnector, "_prepare_port_dict_binding")
488 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
489 @patch.object(vimconnector, "_create_new_port")
490 @patch.object(vimconnector, "_set_fixed_ip")
491 def test_create_port(
492 self,
493 mock_set_fixed_ip,
494 mock_create_new_port,
495 mock_prepare_port_dict_mac_ip_addr,
496 mock_prepare_port_dict_binding,
497 mock_prepare_port_dict_security_groups,
498 ):
499 """Net has name, type, net-id."""
501 net = {
502 "net_id": net_id,
503 "name": "management",
504 "type": "virtual",
505 }
506 created_items = {}
507 new_port = {
508 "port": {
509 "id": net_id,
510 "mac_address": mac_address,
511 "name": "management",
512 "fixed_ips": [{"ip_address": ip_addr1}],
513 },
514 }
515 mock_create_new_port.return_value = new_port
516 expected_port = {
517 "port-id": net_id,
518 "tag": "management",
519 }
520 port_dict = {
521 "network_id": net_id,
522 "name": "management",
523 "admin_state_up": True,
524 }
525 security_group_name = None
527 new_port_result, port_result = self.vimconn._create_port(
528 net, name, created_items
529 )
531 self.assertDictEqual(new_port_result, new_port)
532 self.assertDictEqual(port_result, expected_port)
534 mock_prepare_port_dict_security_groups.assert_called_once_with(
535 net, port_dict, security_group_name
536 )
537 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
538 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
539 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
540 mock_set_fixed_ip.assert_called_once_with(new_port, net)
542 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
543 @patch.object(vimconnector, "_prepare_port_dict_binding")
544 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
545 @patch.object(vimconnector, "_create_new_port")
546 @patch.object(vimconnector, "_set_fixed_ip")
547 def test_create_port_no_port_name(
548 self,
549 mock_set_fixed_ip,
550 mock_create_new_port,
551 mock_prepare_port_dict_mac_ip_addr,
552 mock_prepare_port_dict_binding,
553 mock_prepare_port_dict_security_groups,
554 ):
555 """Net has no name."""
556 net = {
557 "net_id": net_id,
558 "type": "virtual",
559 }
560 created_items = {}
561 new_port = {
562 "port": {
563 "id": net_id,
564 "mac_address": mac_address,
565 "name": name,
566 "fixed_ips": [{"ip_address": ip_addr1}],
567 },
568 }
569 mock_create_new_port.return_value = new_port
570 expected_port = {
571 "port-id": net_id,
572 "tag": name,
573 }
574 port_dict = {
575 "network_id": net_id,
576 "admin_state_up": True,
577 "name": name,
578 }
579 security_group_name = None
581 new_port_result, port_result = self.vimconn._create_port(
582 net, name, created_items
583 )
585 self.assertDictEqual(new_port_result, new_port)
586 self.assertDictEqual(port_result, expected_port)
588 mock_prepare_port_dict_security_groups.assert_called_once_with(
589 net, port_dict, security_group_name
590 )
591 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
592 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
593 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
594 mock_set_fixed_ip.assert_called_once_with(new_port, net)
596 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
597 @patch.object(vimconnector, "_prepare_port_dict_binding")
598 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
599 @patch.object(vimconnector, "_create_new_port")
600 @patch.object(vimconnector, "_set_fixed_ip")
601 def test_create_port_nova_api_version_smaller_than_232(
602 self,
603 mock_set_fixed_ip,
604 mock_create_new_port,
605 mock_prepare_port_dict_mac_ip_addr,
606 mock_prepare_port_dict_binding,
607 mock_prepare_port_dict_security_groups,
608 ):
609 """Nova api version is smaller than 2.32."""
610 self.vimconn.nova.api_version.get_string.return_value = "2.30"
611 net = {
612 "net_id": net_id,
613 "type": "virtual",
614 }
615 created_items = {}
616 new_port = {
617 "port": {
618 "id": net_id,
619 "mac_address": mac_address,
620 "name": name,
621 "fixed_ips": [{"ip_address": ip_addr1}],
622 },
623 }
624 mock_create_new_port.return_value = new_port
625 expected_port = {
626 "port-id": net_id,
627 }
628 port_dict = {
629 "network_id": net_id,
630 "admin_state_up": True,
631 "name": name,
632 }
633 security_group_name = None
635 new_port_result, port_result = self.vimconn._create_port(
636 net, name, created_items
637 )
639 self.assertDictEqual(new_port_result, new_port)
640 self.assertDictEqual(port_result, expected_port)
642 mock_prepare_port_dict_security_groups.assert_called_once_with(
643 net, port_dict, security_group_name
644 )
645 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
646 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
647 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
648 mock_set_fixed_ip.assert_called_once_with(new_port, net)
650 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
651 @patch.object(vimconnector, "_prepare_port_dict_binding")
652 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
653 @patch.object(vimconnector, "_create_new_port")
654 @patch.object(vimconnector, "_set_fixed_ip")
655 def test_create_port_create_new_port_raise_exception(
656 self,
657 mock_set_fixed_ip,
658 mock_create_new_port,
659 mock_prepare_port_dict_mac_ip_addr,
660 mock_prepare_port_dict_binding,
661 mock_prepare_port_dict_security_groups,
662 ):
663 """_create_new_port method raises exception."""
664 net = {
665 "net_id": net_id,
666 "type": "virtual",
667 }
668 created_items = {}
669 mock_create_new_port.side_effect = Exception
670 port_dict = {
671 "network_id": net_id,
672 "admin_state_up": True,
673 "name": name,
674 }
675 security_group_name = None
677 with self.assertRaises(Exception):
678 self.vimconn._create_port(net, name, created_items)
680 mock_prepare_port_dict_security_groups.assert_called_once_with(
681 net, port_dict, security_group_name
682 )
683 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
684 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
685 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
686 mock_set_fixed_ip.assert_not_called()
688 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
689 @patch.object(vimconnector, "_prepare_port_dict_binding")
690 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
691 @patch.object(vimconnector, "_create_new_port")
692 @patch.object(vimconnector, "_set_fixed_ip")
693 def test_create_port_create_sec_groups_raises_exception(
694 self,
695 mock_set_fixed_ip,
696 mock_create_new_port,
697 mock_prepare_port_dict_mac_ip_addr,
698 mock_prepare_port_dict_binding,
699 mock_prepare_port_dict_security_groups,
700 ):
701 """_prepare_port_dict_security_groups method raises exception."""
702 net = {
703 "net_id": net_id,
704 "type": "virtual",
705 }
706 created_items = {}
707 mock_prepare_port_dict_security_groups.side_effect = Exception
708 port_dict = {
709 "network_id": net_id,
710 "admin_state_up": True,
711 "name": name,
712 }
713 security_group_name = None
715 with self.assertRaises(Exception):
716 self.vimconn._create_port(net, name, created_items)
718 mock_prepare_port_dict_security_groups.assert_called_once_with(
719 net, port_dict, security_group_name
720 )
722 mock_prepare_port_dict_binding.assert_not_called()
723 mock_prepare_port_dict_mac_ip_addr.assert_not_called()
724 mock_create_new_port.assert_not_called()
725 mock_set_fixed_ip.assert_not_called()
727 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
728 @patch.object(vimconnector, "_prepare_port_dict_binding")
729 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
730 @patch.object(vimconnector, "_create_new_port")
731 @patch.object(vimconnector, "_set_fixed_ip")
732 def test_create_port_create_port_dict_binding_raise_exception(
733 self,
734 mock_set_fixed_ip,
735 mock_create_new_port,
736 mock_prepare_port_dict_mac_ip_addr,
737 mock_prepare_port_dict_binding,
738 mock_prepare_port_dict_security_groups,
739 ):
740 """_prepare_port_dict_binding method raises exception."""
742 net = {
743 "net_id": net_id,
744 "type": "virtual",
745 }
746 created_items = {}
747 mock_prepare_port_dict_binding.side_effect = Exception
748 port_dict = {
749 "network_id": net_id,
750 "admin_state_up": True,
751 "name": name,
752 }
753 security_group_name = None
755 with self.assertRaises(Exception):
756 self.vimconn._create_port(net, name, created_items)
758 mock_prepare_port_dict_security_groups.assert_called_once_with(
759 net, port_dict, security_group_name
760 )
762 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
764 mock_prepare_port_dict_mac_ip_addr.assert_not_called()
765 mock_create_new_port.assert_not_called()
766 mock_set_fixed_ip.assert_not_called()
768 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
769 @patch.object(vimconnector, "_prepare_port_dict_binding")
770 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
771 @patch.object(vimconnector, "_create_new_port")
772 @patch.object(vimconnector, "_set_fixed_ip")
773 def test_create_port_create_port_mac_ip_addr_raise_exception(
774 self,
775 mock_set_fixed_ip,
776 mock_create_new_port,
777 mock_prepare_port_dict_mac_ip_addr,
778 mock_prepare_port_dict_binding,
779 mock_prepare_port_dict_security_groups,
780 ):
781 """prepare_port_dict_mac_ip_addr method raises exception."""
782 net = {
783 "net_id": net_id,
784 "type": "virtual",
785 }
786 created_items = {}
787 mock_prepare_port_dict_mac_ip_addr.side_effect = Exception
788 port_dict = {
789 "network_id": net_id,
790 "admin_state_up": True,
791 "name": name,
792 }
793 security_group_name = None
795 with self.assertRaises(Exception):
796 self.vimconn._create_port(net, name, created_items)
798 mock_prepare_port_dict_security_groups.assert_called_once_with(
799 net, port_dict, security_group_name
800 )
801 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
802 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
804 mock_create_new_port.assert_not_called()
805 mock_set_fixed_ip.assert_not_called()
807 @patch.object(vimconnector, "_prepare_port_dict_security_groups")
808 @patch.object(vimconnector, "_prepare_port_dict_binding")
809 @patch.object(vimconnector, "_prepare_port_dict_mac_ip_addr")
810 @patch.object(vimconnector, "_create_new_port")
811 @patch.object(vimconnector, "_set_fixed_ip")
812 def test_create_port_create_port_set_fixed_ip_raise_exception(
813 self,
814 mock_set_fixed_ip,
815 mock_create_new_port,
816 mock_prepare_port_dict_mac_ip_addr,
817 mock_prepare_port_dict_binding,
818 mock_prepare_port_dict_security_groups,
819 ):
820 """_set_fixed_ip method raises exception."""
821 net = {
822 "net_id": net_id,
823 "type": "virtual",
824 }
825 created_items = {}
826 mock_set_fixed_ip.side_effect = VimConnException(
827 "Port detail is missing in new_port."
828 )
829 port_dict = {
830 "network_id": net_id,
831 "admin_state_up": True,
832 "name": name,
833 }
834 new_port = {
835 "port": {
836 "id": net_id,
837 "mac_address": mac_address,
838 "name": name,
839 "fixed_ips": [{"ip_address": ip_addr1}],
840 },
841 }
842 security_group_name = None
843 mock_create_new_port.return_value = new_port
845 with self.assertRaises(VimConnException):
846 self.vimconn._create_port(net, name, created_items)
848 mock_prepare_port_dict_security_groups.assert_called_once_with(
849 net, port_dict, security_group_name
850 )
851 mock_prepare_port_dict_binding.assert_called_once_with(net, port_dict)
852 mock_prepare_port_dict_mac_ip_addr.assert_called_once_with(net, port_dict)
853 mock_create_new_port.assert_called_once_with(port_dict, created_items, net)
854 mock_set_fixed_ip.assert_called_once_with(new_port, net)
856 @patch.object(vimconnector, "_reload_connection")
857 @patch.object(vimconnector, "_create_port")
858 def test_prepare_network_for_vm_instance_no_net_id(
859 self, mock_create_port, mock_reload_connection
860 ):
861 """Nets do not have net_id"""
862 mock_reload_connection.side_effect = None
863 created_items = {}
864 net_list = [
865 {
866 "use": "mgmt",
867 "port_security": False,
868 "exit_on_floating_ip_error": False,
869 "port_security_disable_strategy": "full",
870 },
871 {
872 "port_security": True,
873 "exit_on_floating_ip_error": False,
874 "floating_ip": True,
875 },
876 ]
877 net_list_vim = []
878 external_network, no_secured_ports = [], []
879 expected_external_network, expected_no_secured_ports = [], []
880 expected_net_list_vim = []
882 self.vimconn._prepare_network_for_vminstance(
883 name,
884 net_list,
885 created_items,
886 net_list_vim,
887 external_network,
888 no_secured_ports,
889 )
890 self.assertEqual(expected_net_list_vim, net_list_vim)
891 self.assertEqual(external_network, expected_external_network)
892 self.assertEqual(expected_no_secured_ports, no_secured_ports)
894 mock_create_port.assert_not_called()
896 @patch.object(vimconnector, "_reload_connection")
897 @patch.object(vimconnector, "_create_port")
898 def test_prepare_network_for_vm_instance_empty_net_list(
899 self, mock_create_port, mock_reload_connection
900 ):
901 """Net list is empty."""
902 mock_reload_connection.side_effect = None
903 created_items = {}
904 net_list_vim = []
905 external_network, no_secured_ports = [], []
906 expected_external_network, expected_no_secured_ports = [], []
907 expected_net_list_vim = []
909 self.vimconn._prepare_network_for_vminstance(
910 name,
911 net_list,
912 created_items,
913 net_list_vim,
914 external_network,
915 no_secured_ports,
916 )
917 self.assertEqual(expected_net_list_vim, net_list_vim)
918 self.assertEqual(external_network, expected_external_network)
919 self.assertEqual(expected_no_secured_ports, no_secured_ports)
921 mock_create_port.assert_not_called()
923 @patch.object(vimconnector, "_reload_connection")
924 @patch.object(vimconnector, "_create_port")
925 def test_prepare_network_for_vm_instance_use_floating_ip_false_mgmt_net(
926 self, mock_create_port, mock_reload_connection
927 ):
928 """Nets have net-id, floating_ip False, mgmt network."""
929 mock_reload_connection.side_effect = None
930 created_items = {}
931 net_list = [
932 {
933 "net_id": net2_id,
934 "floating_ip": False,
935 "use": "mgmt",
936 }
937 ]
938 net_list_vim = []
939 mock_create_port.side_effect = [
940 (
941 {
942 "port": {
943 "id": port2_id,
944 "mac_address": mac_address,
945 "name": name,
946 },
947 },
948 {"port-dict": port2_id},
949 ),
950 ]
951 external_network, no_secured_ports = [], []
952 expected_external_network, expected_no_secured_ports = [], []
953 expected_net_list_vim = [{"port-dict": port2_id}]
954 self.vimconn._prepare_network_for_vminstance(
955 name,
956 net_list,
957 created_items,
958 net_list_vim,
959 external_network,
960 no_secured_ports,
961 )
962 self.assertEqual(expected_net_list_vim, net_list_vim)
963 self.assertEqual(external_network, expected_external_network)
964 self.assertEqual(expected_no_secured_ports, no_secured_ports)
966 security_group_name = None
967 mock_create_port.assert_called_once_with(
968 {
969 "net_id": net2_id,
970 "floating_ip": False,
971 "use": "mgmt",
972 },
973 name,
974 created_items,
975 security_group_name,
976 )
978 @patch.object(vimconnector, "_reload_connection")
979 def test_prepare_network_for_vm_instance_mgmt_net_net_port_security_and_floating_ip_true(
980 self, mock_reload_connection
981 ):
982 """Nets have net-id, use_floating_ip False in VIM config, mgmt network, net floating_ip is True."""
983 self.vimconn.config["use_floating_ip"] = False
984 mock_create_port = CopyingMock()
985 mock_reload_connection.side_effect = None
986 created_items = {}
987 net_list = [
988 {
989 "net_id": net2_id,
990 "floating_ip": True,
991 "use": "mgmt",
992 }
993 ]
994 net_list_vim = []
995 mock_create_port.side_effect = [
996 (
997 {
998 "port": {
999 "id": port2_id,
1000 "mac_address": mac_address,
1001 "name": name,
1002 },
1003 },
1004 {"port-dict": port2_id},
1005 ),
1006 ]
1007 external_network, no_secured_ports = [], []
1008 expected_external_network = [
1009 {
1010 "net_id": net2_id,
1011 "floating_ip": True,
1012 "use": "mgmt",
1013 "exit_on_floating_ip_error": True,
1014 },
1015 ]
1016 expected_no_secured_ports = []
1017 expected_net_list_vim = [{"port-dict": port2_id}]
1018 with patch.object(vimconnector, "_create_port", mock_create_port):
1019 self.vimconn._prepare_network_for_vminstance(
1020 name,
1021 net_list,
1022 created_items,
1023 net_list_vim,
1024 external_network,
1025 no_secured_ports,
1026 )
1027 self.assertEqual(expected_net_list_vim, net_list_vim)
1028 self.assertEqual(external_network, expected_external_network)
1029 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1031 security_group_name = None
1032 mock_create_port.assert_called_once_with(
1033 {
1034 "net_id": net2_id,
1035 "floating_ip": True,
1036 "use": "mgmt",
1037 },
1038 name,
1039 created_items,
1040 security_group_name,
1041 )
1043 @patch.object(vimconnector, "_reload_connection")
1044 def test_prepare_network_for_vm_instance_use_floating_ip_true_mgmt_net_port_security_false(
1045 self, mock_reload_connection
1046 ):
1047 """Nets have net-id, use_floating_ip is True in VIM config, mgmt network, net port security is False."""
1048 mock_create_port = CopyingMock()
1049 self.vimconn.config["use_floating_ip"] = True
1050 self.vimconn.config["no_port_security_extension"] = False
1051 mock_reload_connection.side_effect = None
1052 created_items = {}
1054 net_list = [
1055 {
1056 "net_id": net2_id,
1057 "use": "mgmt",
1058 "port_security": False,
1059 "exit_on_floating_ip_error": False,
1060 "port_security_disable_strategy": "full",
1061 }
1062 ]
1063 net_list_vim = []
1064 mock_create_port.side_effect = [
1065 (
1066 {
1067 "port": {
1068 "id": port2_id,
1069 "mac_address": mac_address,
1070 "name": name,
1071 },
1072 },
1073 {"port-dict": port2_id},
1074 ),
1075 ]
1076 external_network, no_secured_ports = [], []
1077 expected_external_network = [
1078 {
1079 "net_id": net2_id,
1080 "use": "mgmt",
1081 "port_security": False,
1082 "exit_on_floating_ip_error": False,
1083 "port_security_disable_strategy": "full",
1084 "floating_ip": True,
1085 },
1086 ]
1087 expected_no_secured_ports = [(port2_id, "full")]
1088 expected_net_list_vim = [{"port-dict": port2_id}]
1089 with patch.object(vimconnector, "_create_port", mock_create_port):
1090 self.vimconn._prepare_network_for_vminstance(
1091 name,
1092 net_list,
1093 created_items,
1094 net_list_vim,
1095 external_network,
1096 no_secured_ports,
1097 )
1099 security_group_name = None
1100 mock_create_port.assert_called_once_with(
1101 {
1102 "net_id": net2_id,
1103 "use": "mgmt",
1104 "port_security": False,
1105 "exit_on_floating_ip_error": False,
1106 "port_security_disable_strategy": "full",
1107 },
1108 name,
1109 created_items,
1110 security_group_name,
1111 )
1112 self.assertEqual(expected_net_list_vim, net_list_vim)
1113 self.assertEqual(external_network, expected_external_network)
1114 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1116 @patch.object(vimconnector, "_reload_connection")
1117 def test_prepare_network_for_vm_instance_use_fip_true_non_mgmt_net_port_security_false(
1118 self, mock_reload_connection
1119 ):
1120 """Nets have net-id, use_floating_ip True in VIM config, non-mgmt network, port security is False."""
1121 mock_create_port = CopyingMock()
1122 self.vimconn.config["use_floating_ip"] = True
1123 self.vimconn.config["no_port_security_extension"] = False
1124 mock_reload_connection.side_effect = None
1125 created_items = {}
1127 net_list = [
1128 {
1129 "net_id": net2_id,
1130 "use": "other",
1131 "port_security": False,
1132 "port_security_disable_strategy": "full",
1133 }
1134 ]
1135 net_list_vim = []
1136 mock_create_port.side_effect = [
1137 (
1138 {
1139 "port": {
1140 "id": port2_id,
1141 "mac_address": mac_address,
1142 "name": name,
1143 },
1144 },
1145 {"port-dict": port2_id},
1146 ),
1147 ]
1148 external_network, no_secured_ports = [], []
1149 expected_external_network = []
1150 expected_no_secured_ports = [(port2_id, "full")]
1151 expected_net_list_vim = [{"port-dict": port2_id}]
1152 with patch.object(vimconnector, "_create_port", mock_create_port):
1153 self.vimconn._prepare_network_for_vminstance(
1154 name,
1155 net_list,
1156 created_items,
1157 net_list_vim,
1158 external_network,
1159 no_secured_ports,
1160 )
1162 security_group_name = None
1163 mock_create_port.assert_called_once_with(
1164 {
1165 "net_id": net2_id,
1166 "use": "other",
1167 "port_security": False,
1168 "port_security_disable_strategy": "full",
1169 },
1170 name,
1171 created_items,
1172 security_group_name,
1173 )
1174 self.assertEqual(expected_net_list_vim, net_list_vim)
1175 self.assertEqual(external_network, expected_external_network)
1176 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1178 @patch.object(vimconnector, "_reload_connection")
1179 def test_prepare_network_for_vm_instance_use_fip_true_non_mgmt_net_port_security_true(
1180 self, mock_reload_connection
1181 ):
1182 """Nets have net-id, use_floating_ip is True in VIM config, non-mgmt network, net port security is True."""
1183 mock_create_port = CopyingMock()
1184 self.vimconn.config["use_floating_ip"] = True
1185 self.vimconn.config["no_port_security_extension"] = True
1186 mock_reload_connection.side_effect = None
1187 created_items = {}
1189 net_list = [
1190 {
1191 "net_id": net2_id,
1192 "use": "other",
1193 "port_security": True,
1194 "port_security_disable_strategy": "full",
1195 }
1196 ]
1197 net_list_vim = []
1198 mock_create_port.side_effect = [
1199 (
1200 {
1201 "port": {
1202 "id": port2_id,
1203 "mac_address": mac_address,
1204 "name": name,
1205 },
1206 },
1207 {"port-dict": port2_id},
1208 ),
1209 ]
1210 external_network, no_secured_ports = [], []
1211 expected_external_network = []
1212 expected_no_secured_ports = []
1213 expected_net_list_vim = [{"port-dict": port2_id}]
1214 with patch.object(vimconnector, "_create_port", mock_create_port):
1215 self.vimconn._prepare_network_for_vminstance(
1216 name,
1217 net_list,
1218 created_items,
1219 net_list_vim,
1220 external_network,
1221 no_secured_ports,
1222 )
1224 security_group_name = None
1225 mock_create_port.assert_called_once_with(
1226 {
1227 "net_id": net2_id,
1228 "use": "other",
1229 "port_security": True,
1230 "port_security_disable_strategy": "full",
1231 },
1232 name,
1233 created_items,
1234 security_group_name,
1235 )
1236 self.assertEqual(expected_net_list_vim, net_list_vim)
1237 self.assertEqual(external_network, expected_external_network)
1238 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1240 @patch.object(vimconnector, "_reload_connection")
1241 def test_prepare_network_for_vm_instance_create_port_raise_exception(
1242 self, mock_reload_connection
1243 ):
1244 """_create_port method raise exception."""
1245 mock_create_port = CopyingMock()
1246 self.vimconn.config["use_floating_ip"] = True
1247 self.vimconn.config["no_port_security_extension"] = True
1248 mock_reload_connection.side_effect = None
1249 created_items = {}
1251 net_list = [
1252 {
1253 "net_id": net2_id,
1254 "use": "other",
1255 "port_security": True,
1256 "port_security_disable_strategy": "full",
1257 }
1258 ]
1259 net_list_vim = []
1260 mock_create_port.side_effect = KeyError
1261 external_network, no_secured_ports = [], []
1262 expected_external_network = []
1263 expected_no_secured_ports = []
1264 expected_net_list_vim = []
1265 with patch.object(vimconnector, "_create_port", mock_create_port):
1266 with self.assertRaises(Exception) as err:
1267 self.vimconn._prepare_network_for_vminstance(
1268 name,
1269 net_list,
1270 created_items,
1271 net_list_vim,
1272 external_network,
1273 no_secured_ports,
1274 )
1276 self.assertEqual(type(err.exception), KeyError)
1278 security_group_name = None
1279 mock_create_port.assert_called_once_with(
1280 {
1281 "net_id": net2_id,
1282 "use": "other",
1283 "port_security": True,
1284 "port_security_disable_strategy": "full",
1285 },
1286 name,
1287 created_items,
1288 security_group_name,
1289 )
1290 self.assertEqual(expected_net_list_vim, net_list_vim)
1291 self.assertEqual(external_network, expected_external_network)
1292 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1294 @patch.object(vimconnector, "_reload_connection")
1295 def test_prepare_network_for_vm_instance_reload_connection_raise_exception(
1296 self, mock_reload_connection
1297 ):
1298 """_reload_connection method raises exception."""
1299 mock_create_port = CopyingMock()
1300 mock_reload_connection.side_effect = VimConnConnectionException(
1301 "Connection failed."
1302 )
1303 self.vimconn.config["use_floating_ip"] = True
1304 self.vimconn.config["no_port_security_extension"] = True
1305 created_items = {}
1307 net_list = [
1308 {
1309 "net_id": net2_id,
1310 "use": "other",
1311 "port_security": True,
1312 "port_security_disable_strategy": "full",
1313 }
1314 ]
1315 net_list_vim = []
1316 mock_create_port.side_effect = None
1317 external_network, no_secured_ports = [], []
1318 expected_external_network = []
1319 expected_no_secured_ports = []
1320 expected_net_list_vim = []
1321 with patch.object(vimconnector, "_create_port", mock_create_port):
1322 with self.assertRaises(Exception) as err:
1323 self.vimconn._prepare_network_for_vminstance(
1324 name,
1325 net_list,
1326 created_items,
1327 net_list_vim,
1328 external_network,
1329 no_secured_ports,
1330 )
1332 self.assertEqual(type(err.exception), VimConnConnectionException)
1333 self.assertEqual(str(err.exception), "Connection failed.")
1334 mock_reload_connection.assert_called_once()
1335 mock_create_port.assert_not_called()
1336 self.assertEqual(expected_net_list_vim, net_list_vim)
1337 self.assertEqual(external_network, expected_external_network)
1338 self.assertEqual(expected_no_secured_ports, no_secured_ports)
1340 def test_prepare_persistent_root_volumes_vim_using_volume_id(self):
1341 """Existing persistent root volume with vim_volume_id."""
1342 storage_av_zone = ["nova"]
1343 base_disk_index = ord("a")
1344 disk = {"vim_volume_id": volume_id}
1345 block_device_mapping = {}
1346 existing_vim_volumes = []
1347 created_items = {}
1348 expected_boot_vol_id = None
1349 expected_block_device_mapping = {"vda": volume_id}
1350 expected_existing_vim_volumes = [{"id": volume_id}]
1351 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
1352 name,
1353 storage_av_zone,
1354 disk,
1355 base_disk_index,
1356 block_device_mapping,
1357 existing_vim_volumes,
1358 created_items,
1359 )
1360 self.assertEqual(boot_volume_id, expected_boot_vol_id)
1361 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
1362 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
1363 self.vimconn.cinder.volumes.create.assert_not_called()
1365 @patch.object(vimconnector, "update_block_device_mapping")
1366 def test__prepare_shared_volumes_vim_using_volume_id(
1367 self, mock_update_block_device_mapping
1368 ):
1369 """Existing persistent non root volume with vim_volume_id.
1370 class Volume:
1371 def __init__(self, s, type="__DEFAULT__", name="", id=""):
1372 self.status = s
1373 self.volume_type = type
1374 self.name = name
1375 self.id = id
1376 volumes = {"shared-volume": volume_id4}
1378 The device mappeing BEFORE is: {}
1379 The device mappeing AFTER is: {'vdb': '8ca50cc6-a779-4513-a1f3-900b8b3987d2'}
1380 """
1381 base_disk_index = ord("b")
1382 disk = {"name": "shared-volume"}
1383 block_device_mapping = {}
1384 existing_vim_volumes = []
1385 created_items = {}
1386 expected_block_device_mapping = {}
1387 self.vimconn.cinder.volumes.list.return_value = [
1388 Volume("available", "multiattach", "shared-volume", volume_id4)
1389 ]
1390 self.vimconn.cinder.volumes.get.return_value.id = volume_id4
1391 self.vimconn.cinder.volumes.get.return_value.status = "available"
1392 self.vimconn._prepare_shared_volumes(
1393 name,
1394 disk,
1395 base_disk_index,
1396 block_device_mapping,
1397 existing_vim_volumes,
1398 created_items,
1399 )
1400 self.vimconn.cinder.volumes.get.assert_called_with(volume_id4)
1401 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
1403 @patch.object(vimconnector, "update_block_device_mapping")
1404 def test_prepare_persistent_non_root_volumes_vim_using_volume_id(
1405 self, mock_update_block_device_mapping
1406 ):
1407 """Existing persistent non root volume with vim_volume_id."""
1408 storage_av_zone = ["nova"]
1409 base_disk_index = ord("b")
1410 disk = {"vim_volume_id": volume_id}
1411 block_device_mapping = {}
1412 existing_vim_volumes = []
1413 created_items = {}
1414 expected_block_device_mapping = {"vdb": volume_id}
1415 expected_existing_vim_volumes = [{"id": volume_id}]
1416 self.vimconn._prepare_non_root_persistent_volumes(
1417 name,
1418 disk,
1419 storage_av_zone,
1420 block_device_mapping,
1421 base_disk_index,
1422 existing_vim_volumes,
1423 created_items,
1424 )
1425 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
1426 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
1427 self.vimconn.cinder.volumes.create.assert_not_called()
1428 mock_update_block_device_mapping.assert_not_called()
1430 @patch.object(vimconnector, "update_block_device_mapping")
1431 def test_prepare_persistent_root_volumes_using_vim_id(
1432 self, mock_update_block_device_mapping
1433 ):
1434 """Existing persistent root volume with vim_id."""
1435 storage_av_zone = ["nova"]
1436 base_disk_index = ord("a")
1437 disk = {"vim_id": volume_id}
1438 block_device_mapping = {}
1439 existing_vim_volumes = []
1440 created_items = {}
1441 expected_boot_vol_id = None
1442 expected_block_device_mapping = {"vda": volume_id}
1443 expected_existing_vim_volumes = [{"id": volume_id}]
1444 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
1445 name,
1446 storage_av_zone,
1447 disk,
1448 base_disk_index,
1449 block_device_mapping,
1450 existing_vim_volumes,
1451 created_items,
1452 )
1453 self.assertEqual(boot_volume_id, expected_boot_vol_id)
1454 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
1455 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
1456 self.vimconn.cinder.volumes.create.assert_not_called()
1457 mock_update_block_device_mapping.assert_not_called()
1459 @patch.object(vimconnector, "update_block_device_mapping")
1460 def test_prepare_persistent_non_root_volumes_using_vim_id(
1461 self, mock_update_block_device_mapping
1462 ):
1463 """Existing persistent root volume with vim_id."""
1464 storage_av_zone = ["nova"]
1465 base_disk_index = ord("b")
1466 disk = {"vim_id": volume_id}
1467 block_device_mapping = {}
1468 existing_vim_volumes = []
1469 created_items = {}
1471 expected_block_device_mapping = {"vdb": volume_id}
1472 expected_existing_vim_volumes = [{"id": volume_id}]
1473 self.vimconn._prepare_non_root_persistent_volumes(
1474 name,
1475 disk,
1476 storage_av_zone,
1477 block_device_mapping,
1478 base_disk_index,
1479 existing_vim_volumes,
1480 created_items,
1481 )
1483 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
1484 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
1485 self.vimconn.cinder.volumes.create.assert_not_called()
1486 mock_update_block_device_mapping.assert_not_called()
1488 @patch.object(vimconnector, "update_block_device_mapping")
1489 def test_prepare_persistent_root_volumes_create(
1490 self, mock_update_block_device_mapping
1491 ):
1492 """Create persistent root volume."""
1493 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
1494 storage_av_zone = ["nova"]
1495 base_disk_index = ord("a")
1496 disk = {"size": 10, "image_id": image_id}
1497 block_device_mapping = {}
1498 existing_vim_volumes = []
1499 created_items = {}
1500 expected_boot_vol_id = volume_id2
1501 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
1502 name,
1503 storage_av_zone,
1504 disk,
1505 base_disk_index,
1506 block_device_mapping,
1507 existing_vim_volumes,
1508 created_items,
1509 )
1510 self.assertEqual(boot_volume_id, expected_boot_vol_id)
1511 self.vimconn.cinder.volumes.create.assert_called_once_with(
1512 size=10,
1513 name="basicvmvda",
1514 imageRef=image_id,
1515 availability_zone=["nova"],
1516 )
1517 mock_update_block_device_mapping.assert_called_once()
1518 _call_mock_update_block_device_mapping = (
1519 mock_update_block_device_mapping.call_args_list
1520 )
1521 self.assertEqual(
1522 _call_mock_update_block_device_mapping[0].kwargs["block_device_mapping"],
1523 block_device_mapping,
1524 )
1525 self.assertEqual(
1526 _call_mock_update_block_device_mapping[0].kwargs["base_disk_index"], 97
1527 )
1528 self.assertEqual(_call_mock_update_block_device_mapping[0].kwargs["disk"], disk)
1529 self.assertEqual(
1530 _call_mock_update_block_device_mapping[0].kwargs["created_items"], {}
1531 )
1533 @patch.object(vimconnector, "update_block_device_mapping")
1534 def test_prepare_persistent_root_volumes_create_with_keep(
1535 self, mock_update_block_device_mapping
1536 ):
1537 """Create persistent root volume, disk has keep parameter."""
1538 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
1539 storage_av_zone = ["nova"]
1540 base_disk_index = ord("a")
1541 disk = {"size": 10, "image_id": image_id, "keep": True}
1542 block_device_mapping = {}
1543 existing_vim_volumes = []
1544 created_items = {}
1545 expected_boot_vol_id = volume_id2
1546 expected_existing_vim_volumes = []
1547 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
1548 name,
1549 storage_av_zone,
1550 disk,
1551 base_disk_index,
1552 block_device_mapping,
1553 existing_vim_volumes,
1554 created_items,
1555 )
1556 self.assertEqual(boot_volume_id, expected_boot_vol_id)
1557 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
1558 self.vimconn.cinder.volumes.create.assert_called_once_with(
1559 size=10,
1560 name="basicvmvda",
1561 imageRef=image_id,
1562 availability_zone=["nova"],
1563 )
1564 mock_update_block_device_mapping.assert_called_once()
1565 _call_mock_update_block_device_mapping = (
1566 mock_update_block_device_mapping.call_args_list
1567 )
1568 self.assertEqual(
1569 _call_mock_update_block_device_mapping[0].kwargs["block_device_mapping"],
1570 block_device_mapping,
1571 )
1572 self.assertEqual(
1573 _call_mock_update_block_device_mapping[0].kwargs["base_disk_index"], 97
1574 )
1575 self.assertEqual(_call_mock_update_block_device_mapping[0].kwargs["disk"], disk)
1576 self.assertEqual(
1577 _call_mock_update_block_device_mapping[0].kwargs["created_items"], {}
1578 )
1580 @patch.object(vimconnector, "update_block_device_mapping")
1581 def test_prepare_persistent_non_root_volumes_create(
1582 self, mock_update_block_device_mapping
1583 ):
1584 """Create persistent non-root volume."""
1585 self.vimconn.cinder = CopyingMock()
1586 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
1587 storage_av_zone = ["nova"]
1588 base_disk_index = ord("a")
1589 disk = {"size": 10}
1590 block_device_mapping = {}
1591 existing_vim_volumes = []
1592 created_items = {}
1593 expected_existing_vim_volumes = []
1594 self.vimconn._prepare_non_root_persistent_volumes(
1595 name,
1596 disk,
1597 storage_av_zone,
1598 block_device_mapping,
1599 base_disk_index,
1600 existing_vim_volumes,
1601 created_items,
1602 )
1604 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
1605 self.vimconn.cinder.volumes.create.assert_called_once_with(
1606 size=10, name="basicvmvda", availability_zone=["nova"]
1607 )
1608 mock_update_block_device_mapping.assert_called_once()
1609 _call_mock_update_block_device_mapping = (
1610 mock_update_block_device_mapping.call_args_list
1611 )
1612 self.assertEqual(
1613 _call_mock_update_block_device_mapping[0].kwargs["block_device_mapping"],
1614 block_device_mapping,
1615 )
1616 self.assertEqual(
1617 _call_mock_update_block_device_mapping[0].kwargs["base_disk_index"], 97
1618 )
1619 self.assertEqual(_call_mock_update_block_device_mapping[0].kwargs["disk"], disk)
1620 self.assertEqual(
1621 _call_mock_update_block_device_mapping[0].kwargs["created_items"], {}
1622 )
1624 @patch.object(vimconnector, "update_block_device_mapping")
1625 def test_prepare_persistent_non_root_volumes_create_with_keep(
1626 self, mock_update_block_device_mapping
1627 ):
1628 """Create persistent non-root volume."""
1629 self.vimconn.cinder = CopyingMock()
1630 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
1631 storage_av_zone = ["nova"]
1632 base_disk_index = ord("a")
1633 disk = {"size": 10, "keep": True}
1634 block_device_mapping = {}
1635 existing_vim_volumes = []
1636 created_items = {}
1637 expected_existing_vim_volumes = []
1638 self.vimconn._prepare_non_root_persistent_volumes(
1639 name,
1640 disk,
1641 storage_av_zone,
1642 block_device_mapping,
1643 base_disk_index,
1644 existing_vim_volumes,
1645 created_items,
1646 )
1648 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
1649 self.vimconn.cinder.volumes.create.assert_called_once_with(
1650 size=10, name="basicvmvda", availability_zone=["nova"]
1651 )
1652 mock_update_block_device_mapping.assert_called_once()
1653 _call_mock_update_block_device_mapping = (
1654 mock_update_block_device_mapping.call_args_list
1655 )
1656 self.assertEqual(
1657 _call_mock_update_block_device_mapping[0].kwargs["block_device_mapping"],
1658 block_device_mapping,
1659 )
1660 self.assertEqual(
1661 _call_mock_update_block_device_mapping[0].kwargs["base_disk_index"], 97
1662 )
1663 self.assertEqual(_call_mock_update_block_device_mapping[0].kwargs["disk"], disk)
1664 self.assertEqual(
1665 _call_mock_update_block_device_mapping[0].kwargs["created_items"], {}
1666 )
1668 @patch.object(vimconnector, "update_block_device_mapping")
1669 def test_new_shared_volumes(self, mock_update_block_device_mapping):
1670 """Create shared volume."""
1672 class MyVolume:
1673 name = "my-shared-volume"
1674 id = volume_id4
1675 availability_zone = ["nova"]
1677 self.vimconn.storage_availability_zone = ["nova"]
1678 self.vimconn.cinder.volumes.create.return_value = MyVolume()
1679 shared_volume_data = {"size": 10, "name": "my-shared-volume"}
1680 result = self.vimconn.new_shared_volumes(shared_volume_data)
1681 self.vimconn.cinder.volumes.create.assert_called_once_with(
1682 size=10,
1683 name="my-shared-volume",
1684 volume_type="multiattach",
1685 availability_zone=["nova"],
1686 )
1687 self.assertEqual(result[0], "my-shared-volume")
1688 self.assertEqual(result[1], volume_id4)
1690 @patch.object(vimconnector, "update_block_device_mapping")
1691 def test_prepare_persistent_root_volumes_create_raise_exception(
1692 self, mock_update_block_device_mapping
1693 ):
1694 """Create persistent root volume raise exception."""
1695 self.vimconn.cinder.volumes.create.side_effect = Exception
1696 storage_av_zone = ["nova"]
1697 base_disk_index = ord("a")
1698 disk = {"size": 10, "image_id": image_id}
1699 block_device_mapping = {}
1700 existing_vim_volumes = []
1701 created_items = {}
1703 with self.assertRaises(Exception):
1704 result = self.vimconn._prepare_persistent_root_volumes(
1705 name,
1706 storage_av_zone,
1707 disk,
1708 base_disk_index,
1709 block_device_mapping,
1710 existing_vim_volumes,
1711 created_items,
1712 )
1714 self.assertEqual(result, None)
1716 self.vimconn.cinder.volumes.create.assert_called_once_with(
1717 size=10,
1718 name="basicvmvda",
1719 imageRef=image_id,
1720 availability_zone=["nova"],
1721 )
1722 self.assertEqual(existing_vim_volumes, [])
1723 self.assertEqual(block_device_mapping, {})
1724 self.assertEqual(created_items, {})
1725 mock_update_block_device_mapping.assert_not_called()
1727 @patch.object(vimconnector, "update_block_device_mapping")
1728 def test_prepare_persistent_non_root_volumes_create_raise_exception(
1729 self, mock_update_block_device_mapping
1730 ):
1731 """Create persistent non-root volume raise exception."""
1732 self.vimconn.cinder.volumes.create.side_effect = Exception
1733 storage_av_zone = ["nova"]
1734 base_disk_index = ord("b")
1735 disk = {"size": 10}
1736 block_device_mapping = {}
1737 existing_vim_volumes = []
1738 created_items = {}
1740 with self.assertRaises(Exception):
1741 self.vimconn._prepare_non_root_persistent_volumes(
1742 name,
1743 disk,
1744 storage_av_zone,
1745 block_device_mapping,
1746 base_disk_index,
1747 existing_vim_volumes,
1748 created_items,
1749 )
1751 self.vimconn.cinder.volumes.create.assert_called_once_with(
1752 size=10, name="basicvmvdb", availability_zone=["nova"]
1753 )
1754 self.assertEqual(existing_vim_volumes, [])
1755 self.assertEqual(block_device_mapping, {})
1756 self.assertEqual(created_items, {})
1757 mock_update_block_device_mapping.assert_not_called()
1759 @patch("time.sleep")
1760 def test_wait_for_created_volumes_availability_volume_status_available(
1761 self, mock_sleep
1762 ):
1763 """Created volume status is available."""
1764 elapsed_time = 5
1765 created_items = {f"volume:{volume_id2}": True}
1766 self.vimconn.cinder.volumes.get.return_value.status = "available"
1768 result = self.vimconn._wait_for_created_volumes_availability(
1769 elapsed_time, created_items
1770 )
1771 self.assertEqual(result, elapsed_time)
1772 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
1773 mock_sleep.assert_not_called()
1775 @patch("time.sleep")
1776 def test_wait_for_existing_volumes_availability_volume_status_available(
1777 self, mock_sleep
1778 ):
1779 """Existing volume status is available."""
1780 elapsed_time = 5
1781 existing_vim_volumes = [{"id": volume_id2}]
1782 self.vimconn.cinder.volumes.get.return_value.status = "available"
1784 result = self.vimconn._wait_for_existing_volumes_availability(
1785 elapsed_time, existing_vim_volumes
1786 )
1787 self.assertEqual(result, elapsed_time)
1788 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
1789 mock_sleep.assert_not_called()
1791 @patch("time.sleep")
1792 def test_wait_for_created_volumes_availability_status_processing_multiple_volumes(
1793 self, mock_sleep
1794 ):
1795 """Created volume status is processing."""
1796 elapsed_time = 5
1797 created_items = {
1798 f"volume:{volume_id2}": True,
1799 f"volume:{volume_id3}": True,
1800 }
1801 self.vimconn.cinder.volumes.get.side_effect = [
1802 Volume("processing"),
1803 Volume("available"),
1804 Volume("available"),
1805 ]
1807 result = self.vimconn._wait_for_created_volumes_availability(
1808 elapsed_time, created_items
1809 )
1810 self.assertEqual(result, 10)
1811 _call_mock_get_volumes = self.vimconn.cinder.volumes.get.call_args_list
1812 self.assertEqual(_call_mock_get_volumes[0][0], (volume_id2,))
1813 self.assertEqual(_call_mock_get_volumes[1][0], (volume_id2,))
1814 self.assertEqual(_call_mock_get_volumes[2][0], (volume_id3,))
1815 mock_sleep.assert_called_with(5)
1816 self.assertEqual(1, mock_sleep.call_count)
1818 @patch("time.sleep")
1819 def test_wait_for_existing_volumes_availability_status_processing_multiple_volumes(
1820 self, mock_sleep
1821 ):
1822 """Existing volume status is processing."""
1823 elapsed_time = 5
1824 existing_vim_volumes = [
1825 {"id": volume_id2},
1826 {"id": "44e0e83-b9uu-4akk-t234-p9cc4811bd4a"},
1827 ]
1828 self.vimconn.cinder.volumes.get.side_effect = [
1829 Volume("processing"),
1830 Volume("available", "multiattach"),
1831 Volume("available"),
1832 ]
1834 result = self.vimconn._wait_for_existing_volumes_availability(
1835 elapsed_time, existing_vim_volumes
1836 )
1837 self.assertEqual(result, 10)
1838 _call_mock_get_volumes = self.vimconn.cinder.volumes.get.call_args_list
1839 self.assertEqual(_call_mock_get_volumes[0][0], (volume_id2,))
1840 self.assertEqual(_call_mock_get_volumes[1][0], (volume_id2,))
1841 self.assertEqual(
1842 _call_mock_get_volumes[2][0], ("44e0e83-b9uu-4akk-t234-p9cc4811bd4a",)
1843 )
1844 mock_sleep.assert_called_with(5)
1845 self.assertEqual(1, mock_sleep.call_count)
1847 @patch("time.sleep")
1848 def test_wait_for_created_volumes_availability_volume_status_processing_timeout(
1849 self, mock_sleep
1850 ):
1851 """Created volume status is processing, elapsed time greater than timeout (1800)."""
1852 elapsed_time = 1805
1853 created_items = {f"volume:{volume_id2}": True}
1854 self.vimconn.cinder.volumes.get.side_effect = [
1855 Volume("processing"),
1856 Volume("processing"),
1857 ]
1858 with patch("time.sleep", mock_sleep):
1859 result = self.vimconn._wait_for_created_volumes_availability(
1860 elapsed_time, created_items
1861 )
1862 self.assertEqual(result, 1805)
1863 self.vimconn.cinder.volumes.get.assert_not_called()
1864 mock_sleep.assert_not_called()
1866 @patch("time.sleep")
1867 def test_wait_for_existing_volumes_availability_volume_status_processing_timeout(
1868 self, mock_sleep
1869 ):
1870 """Exsiting volume status is processing, elapsed time greater than timeout (1800)."""
1871 elapsed_time = 1805
1872 existing_vim_volumes = [{"id": volume_id2}]
1873 self.vimconn.cinder.volumes.get.side_effect = [
1874 Volume("processing"),
1875 Volume("processing"),
1876 ]
1878 result = self.vimconn._wait_for_existing_volumes_availability(
1879 elapsed_time, existing_vim_volumes
1880 )
1881 self.assertEqual(result, 1805)
1882 self.vimconn.cinder.volumes.get.assert_not_called()
1883 mock_sleep.assert_not_called()
1885 @patch("time.sleep")
1886 def test_wait_for_created_volumes_availability_cinder_raise_exception(
1887 self, mock_sleep
1888 ):
1889 """Cinder get volumes raises exception for created volumes."""
1890 elapsed_time = 1000
1891 created_items = {f"volume:{volume_id2}": True}
1892 self.vimconn.cinder.volumes.get.side_effect = Exception
1893 with self.assertRaises(Exception):
1894 result = self.vimconn._wait_for_created_volumes_availability(
1895 elapsed_time, created_items
1896 )
1897 self.assertEqual(result, 1000)
1898 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
1899 mock_sleep.assert_not_called()
1901 @patch("time.sleep")
1902 def test_wait_for_existing_volumes_availability_cinder_raise_exception(
1903 self, mock_sleep
1904 ):
1905 """Cinder get volumes raises exception for existing volumes."""
1906 elapsed_time = 1000
1907 existing_vim_volumes = [{"id": volume_id2}]
1908 self.vimconn.cinder.volumes.get.side_effect = Exception
1909 with self.assertRaises(Exception):
1910 result = self.vimconn._wait_for_existing_volumes_availability(
1911 elapsed_time, existing_vim_volumes
1912 )
1913 self.assertEqual(result, 1000)
1914 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
1915 mock_sleep.assert_not_called()
1917 @patch("time.sleep")
1918 def test_wait_for_created_volumes_availability_no_volume_in_created_items(
1919 self, mock_sleep
1920 ):
1921 """Created_items dict does not have volume-id."""
1922 elapsed_time = 10
1923 created_items = {}
1925 self.vimconn.cinder.volumes.get.side_effect = [None]
1927 result = self.vimconn._wait_for_created_volumes_availability(
1928 elapsed_time, created_items
1929 )
1930 self.assertEqual(result, 10)
1931 self.vimconn.cinder.volumes.get.assert_not_called()
1932 mock_sleep.assert_not_called()
1934 @patch("time.sleep")
1935 def test_wait_for_existing_volumes_availability_no_volume_in_existing_vim_volumes(
1936 self, mock_sleep
1937 ):
1938 """Existing_vim_volumes list does not have volume."""
1939 elapsed_time = 10
1940 existing_vim_volumes = []
1942 self.vimconn.cinder.volumes.get.side_effect = [None]
1944 result = self.vimconn._wait_for_existing_volumes_availability(
1945 elapsed_time, existing_vim_volumes
1946 )
1947 self.assertEqual(result, 10)
1948 self.vimconn.cinder.volumes.get.assert_not_called()
1949 mock_sleep.assert_not_called()
1951 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
1952 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
1953 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
1954 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
1955 def test_prepare_disk_for_vm_instance(
1956 self,
1957 mock_existing_vol_availability,
1958 mock_created_vol_availability,
1959 mock_non_root_volumes,
1960 mock_root_volumes,
1961 ):
1962 """Prepare disks for VM instance successfully."""
1963 existing_vim_volumes = []
1964 created_items = {}
1965 block_device_mapping = {}
1966 storage_av_zone = ["nova"]
1968 mock_root_volumes.return_value = root_vol_id
1969 mock_created_vol_availability.return_value = 10
1970 mock_existing_vol_availability.return_value = 15
1971 self.vimconn.cinder = CopyingMock()
1972 self.vimconn._prepare_disk_for_vminstance(
1973 name,
1974 existing_vim_volumes,
1975 created_items,
1976 storage_av_zone,
1977 block_device_mapping,
1978 disk_list2,
1979 )
1980 self.vimconn.cinder.volumes.set_bootable.assert_called_once_with(
1981 root_vol_id, True
1982 )
1983 mock_created_vol_availability.assert_called_once_with(0, created_items)
1984 mock_existing_vol_availability.assert_called_once_with(10, existing_vim_volumes)
1985 self.assertEqual(mock_root_volumes.call_count, 1)
1986 self.assertEqual(mock_non_root_volumes.call_count, 1)
1987 mock_root_volumes.assert_called_once_with(
1988 name="basicvm",
1989 storage_av_zone=["nova"],
1990 disk={"size": 10, "image_id": image_id},
1991 base_disk_index=97,
1992 block_device_mapping={},
1993 existing_vim_volumes=[],
1994 created_items={},
1995 )
1996 mock_non_root_volumes.assert_called_once_with(
1997 name="basicvm",
1998 disk={"size": 20},
1999 storage_av_zone=["nova"],
2000 base_disk_index=98,
2001 block_device_mapping={},
2002 existing_vim_volumes=[],
2003 created_items={},
2004 )
2006 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2007 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2008 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2009 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2010 def test_prepare_disk_for_vm_instance_timeout_exceeded(
2011 self,
2012 mock_existing_vol_availability,
2013 mock_created_vol_availability,
2014 mock_non_root_volumes,
2015 mock_root_volumes,
2016 ):
2017 """Timeout exceeded while waiting for disks."""
2018 existing_vim_volumes = []
2019 created_items = {}
2020 storage_av_zone = ["nova"]
2021 block_device_mapping = {}
2023 mock_root_volumes.return_value = root_vol_id
2024 mock_created_vol_availability.return_value = 1700
2025 mock_existing_vol_availability.return_value = 1900
2027 with self.assertRaises(VimConnException) as err:
2028 self.vimconn._prepare_disk_for_vminstance(
2029 name,
2030 existing_vim_volumes,
2031 created_items,
2032 storage_av_zone,
2033 block_device_mapping,
2034 disk_list2,
2035 )
2036 self.assertEqual(
2037 str(err.exception), "Timeout creating volumes for instance basicvm"
2038 )
2039 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2040 mock_created_vol_availability.assert_called_once_with(0, created_items)
2041 mock_existing_vol_availability.assert_called_once_with(
2042 1700, existing_vim_volumes
2043 )
2044 self.assertEqual(mock_root_volumes.call_count, 1)
2045 self.assertEqual(mock_non_root_volumes.call_count, 1)
2046 mock_root_volumes.assert_called_once_with(
2047 name="basicvm",
2048 storage_av_zone=["nova"],
2049 disk={"size": 10, "image_id": image_id},
2050 base_disk_index=97,
2051 block_device_mapping={},
2052 existing_vim_volumes=[],
2053 created_items={},
2054 )
2055 mock_non_root_volumes.assert_called_once_with(
2056 name="basicvm",
2057 disk={"size": 20},
2058 storage_av_zone=["nova"],
2059 base_disk_index=98,
2060 block_device_mapping={},
2061 existing_vim_volumes=[],
2062 created_items={},
2063 )
2065 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2066 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2067 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2068 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2069 def test_prepare_disk_for_vm_instance_empty_disk_list(
2070 self,
2071 mock_existing_vol_availability,
2072 mock_created_vol_availability,
2073 mock_non_root_volumes,
2074 mock_root_volumes,
2075 ):
2076 """Disk list is empty."""
2077 existing_vim_volumes = []
2078 created_items = {}
2079 block_device_mapping = {}
2080 storage_av_zone = ["nova"]
2081 mock_created_vol_availability.return_value = 2
2082 mock_existing_vol_availability.return_value = 3
2084 self.vimconn._prepare_disk_for_vminstance(
2085 name,
2086 existing_vim_volumes,
2087 created_items,
2088 storage_av_zone,
2089 block_device_mapping,
2090 disk_list,
2091 )
2092 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2093 mock_created_vol_availability.assert_called_once_with(0, created_items)
2094 mock_existing_vol_availability.assert_called_once_with(2, existing_vim_volumes)
2095 mock_root_volumes.assert_not_called()
2096 mock_non_root_volumes.assert_not_called()
2098 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2099 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2100 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2101 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2102 def test_prepare_disk_for_vm_instance_persistent_root_volume_error(
2103 self,
2104 mock_existing_vol_availability,
2105 mock_created_vol_availability,
2106 mock_non_root_volumes,
2107 mock_root_volumes,
2108 ):
2109 """Persistent root volumes preparation raises error."""
2110 existing_vim_volumes = []
2111 created_items = {}
2112 storage_av_zone = ["nova"]
2113 block_device_mapping = {}
2115 mock_root_volumes.side_effect = Exception()
2116 mock_created_vol_availability.return_value = 10
2117 mock_existing_vol_availability.return_value = 15
2119 with self.assertRaises(Exception):
2120 self.vimconn._prepare_disk_for_vminstance(
2121 name,
2122 existing_vim_volumes,
2123 created_items,
2124 storage_av_zone,
2125 block_device_mapping,
2126 disk_list2,
2127 )
2128 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2129 mock_created_vol_availability.assert_not_called()
2130 mock_existing_vol_availability.assert_not_called()
2131 mock_root_volumes.assert_called_once_with(
2132 name="basicvm",
2133 storage_av_zone=["nova"],
2134 disk={"size": 10, "image_id": image_id},
2135 base_disk_index=97,
2136 block_device_mapping={},
2137 existing_vim_volumes=[],
2138 created_items={},
2139 )
2140 mock_non_root_volumes.assert_not_called()
2142 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2143 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2144 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2145 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2146 def test_prepare_disk_for_vm_instance_non_root_volume_error(
2147 self,
2148 mock_existing_vol_availability,
2149 mock_created_vol_availability,
2150 mock_non_root_volumes,
2151 mock_root_volumes,
2152 ):
2153 """Non-root volumes preparation raises error."""
2154 existing_vim_volumes = []
2155 created_items = {}
2156 storage_av_zone = ["nova"]
2157 block_device_mapping = {}
2159 mock_root_volumes.return_value = root_vol_id
2160 mock_non_root_volumes.side_effect = Exception
2162 with self.assertRaises(Exception):
2163 self.vimconn._prepare_disk_for_vminstance(
2164 name,
2165 existing_vim_volumes,
2166 created_items,
2167 storage_av_zone,
2168 block_device_mapping,
2169 disk_list2,
2170 )
2171 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2172 mock_created_vol_availability.assert_not_called()
2173 mock_existing_vol_availability.assert_not_called()
2174 self.assertEqual(mock_root_volumes.call_count, 1)
2175 self.assertEqual(mock_non_root_volumes.call_count, 1)
2176 mock_root_volumes.assert_called_once_with(
2177 name="basicvm",
2178 storage_av_zone=["nova"],
2179 disk={"size": 10, "image_id": image_id},
2180 base_disk_index=97,
2181 block_device_mapping={},
2182 existing_vim_volumes=[],
2183 created_items={},
2184 )
2185 mock_non_root_volumes.assert_called_once_with(
2186 name="basicvm",
2187 disk={"size": 20},
2188 storage_av_zone=["nova"],
2189 base_disk_index=98,
2190 block_device_mapping={},
2191 existing_vim_volumes=[],
2192 created_items={},
2193 )
2195 def test_find_external_network_for_floating_ip_no_external_network(self):
2196 """External network could not be found."""
2197 self.vimconn.neutron.list_networks.return_value = {
2198 "networks": [
2199 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": False}
2200 ]
2201 }
2202 with self.assertRaises(VimConnException) as err:
2203 self.vimconn._find_the_external_network_for_floating_ip()
2204 self.assertEqual(
2205 str(err.exception),
2206 "Cannot create floating_ip automatically since no external network is present",
2207 )
2209 def test_find_external_network_for_floating_one_external_network(self):
2210 """One external network has been found."""
2211 self.vimconn.neutron.list_networks.return_value = {
2212 "networks": [
2213 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": True}
2214 ]
2215 }
2216 expected_result = "408b73-r9cc-5a6a-a270-82cc4811bd4a"
2217 result = self.vimconn._find_the_external_network_for_floating_ip()
2218 self.assertEqual(result, expected_result)
2220 def test_find_external_network_for_floating_neutron_raises_exception(self):
2221 """Neutron list networks raises exception."""
2222 self.vimconn.neutron.list_networks.side_effect = Exception
2223 with self.assertRaises(Exception):
2224 self.vimconn._find_the_external_network_for_floating_ip()
2226 def test_find_external_network_for_floating_several_external_network(self):
2227 """Several exernal networks has been found."""
2228 self.vimconn.neutron.list_networks.return_value = {
2229 "networks": [
2230 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": True},
2231 {"id": "608b73-y9cc-5a6a-a270-12cc4811bd4a", "router:external": True},
2232 ]
2233 }
2234 with self.assertRaises(VimConnException) as err:
2235 self.vimconn._find_the_external_network_for_floating_ip()
2236 self.assertEqual(
2237 str(err.exception),
2238 "Cannot create floating_ip automatically since multiple external networks are present",
2239 )
2241 def test_neutron_create_float_ip(self):
2242 """Floating ip creation is successful."""
2243 param = {"net_id": "408b73-r9cc-5a6a-a270-p2cc4811bd9a"}
2244 created_items = {}
2245 self.vimconn.neutron.create_floatingip.return_value = {
2246 "floatingip": {"id": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2247 }
2248 expected_created_items = {
2249 "floating_ip:308b73-t9cc-1a6a-a270-12cc4811bd4a": True
2250 }
2251 self.vimconn._neutron_create_float_ip(param, created_items)
2252 self.assertEqual(created_items, expected_created_items)
2254 def test_neutron_create_float_ip_exception_occurred(self):
2255 """Floating ip could not be created."""
2256 param = {
2257 "floatingip": {
2258 "floating_network_id": "408b73-r9cc-5a6a-a270-p2cc4811bd9a",
2259 "tenant_id": "308b73-19cc-8a6a-a270-02cc4811bd9a",
2260 }
2261 }
2262 created_items = {}
2263 self.vimconn.neutron = CopyingMock()
2264 self.vimconn.neutron.create_floatingip.side_effect = Exception(
2265 "Neutron floating ip create exception occurred."
2266 )
2267 with self.assertRaises(VimConnException) as err:
2268 self.vimconn._neutron_create_float_ip(param, created_items)
2269 self.assertEqual(created_items, {})
2270 self.assertEqual(
2271 str(err.exception),
2272 "Exception: Cannot create new floating_ip Neutron floating ip create exception occurred.",
2273 )
2275 @patch.object(vimconnector, "_neutron_create_float_ip")
2276 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2277 def test_create_floating_ip_pool_id_available(
2278 self, mock_find_ext_network, mock_create_float_ip
2279 ):
2280 """Floating ip creation, ip pool is available."""
2281 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2282 created_items = {}
2283 expected_param = {
2284 "floatingip": {
2285 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2286 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2287 }
2288 }
2289 self.vimconn._create_floating_ip(floating_network, self.server, created_items)
2290 mock_find_ext_network.assert_not_called()
2291 mock_create_float_ip.assert_called_once_with(expected_param, {})
2293 @patch.object(vimconnector, "_neutron_create_float_ip")
2294 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2295 def test_create_floating_ip_finding_pool_id(
2296 self, mock_find_ext_network, mock_create_float_ip
2297 ):
2298 """Floating ip creation, pool id need to be found."""
2299 floating_network = {"floating_ip": True}
2300 created_items = {}
2301 mock_find_ext_network.return_value = "308b73-t9cc-1a6a-a270-12cc4811bd4a"
2302 expected_param = {
2303 "floatingip": {
2304 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2305 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2306 }
2307 }
2308 self.vimconn._create_floating_ip(floating_network, self.server, created_items)
2309 mock_find_ext_network.assert_called_once()
2310 mock_create_float_ip.assert_called_once_with(expected_param, {})
2312 @patch.object(vimconnector, "_neutron_create_float_ip")
2313 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2314 def test_create_floating_ip_neutron_create_floating_ip_exception(
2315 self, mock_find_ext_network, mock_create_float_ip
2316 ):
2317 """Neutron creat floating ip raises error."""
2318 floating_network = {"floating_ip": True}
2319 created_items = {}
2320 mock_create_float_ip.side_effect = VimConnException(
2321 "Can not create floating ip."
2322 )
2323 mock_find_ext_network.return_value = "308b73-t9cc-1a6a-a270-12cc4811bd4a"
2324 expected_param = {
2325 "floatingip": {
2326 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2327 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2328 }
2329 }
2331 with self.assertRaises(VimConnException) as err:
2332 self.vimconn._create_floating_ip(
2333 floating_network, self.server, created_items
2334 )
2335 self.assertEqual(str(err.exception), "Can not create floating ip.")
2336 mock_find_ext_network.assert_called_once()
2337 mock_create_float_ip.assert_called_once_with(expected_param, {})
2339 @patch.object(vimconnector, "_neutron_create_float_ip")
2340 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2341 def test_create_floating_ip_can_not_find_pool_id(
2342 self, mock_find_ext_network, mock_create_float_ip
2343 ):
2344 """Floating ip creation, pool id could not be found."""
2345 floating_network = {"floating_ip": True}
2346 created_items = {}
2347 mock_find_ext_network.side_effect = VimConnException(
2348 "Cannot create floating_ip automatically since no external network is present"
2349 )
2350 with self.assertRaises(VimConnException) as err:
2351 self.vimconn._create_floating_ip(
2352 floating_network, self.server, created_items
2353 )
2354 self.assertEqual(
2355 str(err.exception),
2356 "Cannot create floating_ip automatically since no external network is present",
2357 )
2358 mock_find_ext_network.assert_called_once()
2359 mock_create_float_ip.assert_not_called()
2361 def test_find_floating_ip_get_free_floating_ip(self):
2362 """Get free floating ips successfully."""
2363 floating_ips = [
2364 {
2365 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2366 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2367 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
2368 }
2369 ]
2370 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2371 expected_result = "508b73-o9cc-5a6a-a270-72cc4811bd8"
2373 result = self.vimconn._find_floating_ip(
2374 self.server, floating_ips, floating_network
2375 )
2376 self.assertEqual(result, expected_result)
2378 def test_find_floating_ip_different_floating_network_id(self):
2379 """Floating network id is different with floating_ip of floating network."""
2380 floating_ips = [
2381 {
2382 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2383 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
2384 }
2385 ]
2386 floating_network = {"floating_ip": "508b73-t9cc-1a6a-a270-12cc4811bd4a"}
2388 result = self.vimconn._find_floating_ip(
2389 self.server, floating_ips, floating_network
2390 )
2391 self.assertEqual(result, None)
2393 def test_find_floating_ip_different_fip_tenant(self):
2394 """Items in floating_ips has port_id, tenant_is is not same with server tenant id."""
2395 floating_ips = [
2396 {
2397 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2398 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2399 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
2400 "tenant_id": self.server.id,
2401 }
2402 ]
2403 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2404 mock_create_floating_ip = CopyingMock()
2405 with patch.object(vimconnector, "_create_floating_ip", mock_create_floating_ip):
2406 result = self.vimconn._find_floating_ip(
2407 self.server, floating_ips, floating_network
2408 )
2409 self.assertEqual(result, None)
2411 @patch("time.sleep")
2412 def test_assign_floating_ip(self, mock_sleep):
2413 """Assign floating ip successfully."""
2414 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
2415 floating_network = {"vim_id": floating_network_vim_id}
2416 fip = {
2417 "port_id": floating_network_vim_id,
2418 "floating_network_id": "p08b73-e9cc-5a6a-t270-82cc4811bd4a",
2419 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
2420 "tenant_id": "k08b73-e9cc-5a6a-t270-82cc4811bd4a",
2421 }
2422 self.vimconn.neutron.update_floatingip.side_effect = None
2423 self.vimconn.neutron.show_floatingip.return_value = fip
2424 expected_result = fip
2426 result = self.vimconn._assign_floating_ip(free_floating_ip, floating_network)
2427 self.assertEqual(result, expected_result)
2428 self.vimconn.neutron.update_floatingip.assert_called_once_with(
2429 free_floating_ip,
2430 {"floatingip": {"port_id": floating_network_vim_id}},
2431 )
2432 mock_sleep.assert_called_once_with(5)
2433 self.vimconn.neutron.show_floatingip.assert_called_once_with(free_floating_ip)
2435 @patch("time.sleep")
2436 def test_assign_floating_ip_update_floating_ip_exception(self, mock_sleep):
2437 """Neutron update floating ip raises exception."""
2438 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
2439 floating_network = {"vim_id": floating_network_vim_id}
2440 self.vimconn.neutron = CopyingMock()
2441 self.vimconn.neutron.update_floatingip.side_effect = Exception(
2442 "Floating ip is not updated."
2443 )
2445 with self.assertRaises(Exception) as err:
2446 result = self.vimconn._assign_floating_ip(
2447 free_floating_ip, floating_network
2448 )
2449 self.assertEqual(result, None)
2450 self.assertEqual(str(err.exception), "Floating ip is not updated.")
2452 self.vimconn.neutron.update_floatingip.assert_called_once_with(
2453 free_floating_ip,
2454 {"floatingip": {"port_id": floating_network_vim_id}},
2455 )
2456 mock_sleep.assert_not_called()
2457 self.vimconn.neutron.show_floatingip.assert_not_called()
2459 @patch("time.sleep")
2460 def test_assign_floating_ip_show_floating_ip_exception(self, mock_sleep):
2461 """Neutron show floating ip raises exception."""
2462 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
2463 floating_network = {"vim_id": floating_network_vim_id}
2464 self.vimconn.neutron.update_floatingip.side_effect = None
2465 self.vimconn.neutron.show_floatingip.side_effect = Exception(
2466 "Floating ip could not be shown."
2467 )
2469 with self.assertRaises(Exception) as err:
2470 result = self.vimconn._assign_floating_ip(
2471 free_floating_ip, floating_network
2472 )
2473 self.assertEqual(result, None)
2474 self.assertEqual(str(err.exception), "Floating ip could not be shown.")
2475 self.vimconn.neutron.update_floatingip.assert_called_once_with(
2476 free_floating_ip,
2477 {"floatingip": {"port_id": floating_network_vim_id}},
2478 )
2479 mock_sleep.assert_called_once_with(5)
2480 self.vimconn.neutron.show_floatingip.assert_called_once_with(free_floating_ip)
2482 @patch("random.shuffle")
2483 @patch.object(vimconnector, "_find_floating_ip")
2484 def test_get_free_floating_ip(self, mock_find_floating_ip, mock_shuffle):
2485 """Get free floating ip successfully."""
2486 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2487 floating_ips = [
2488 {
2489 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2490 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2491 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
2492 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
2493 },
2494 {
2495 "port_id": "508b73-r9cc-5a6a-5270-o2cc4811bd4a",
2496 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2497 "id": "208b73-o9cc-5a6a-a270-52cc4811bd8",
2498 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
2499 },
2500 ]
2501 self.vimconn.neutron.list_floatingips.return_value = {
2502 "floatingips": floating_ips
2503 }
2504 mock_find_floating_ip.return_value = "508b73-o9cc-5a6a-a270-72cc4811bd8"
2505 expected_result = "508b73-o9cc-5a6a-a270-72cc4811bd8"
2507 result = self.vimconn._get_free_floating_ip(self.server, floating_network)
2508 self.assertEqual(result, expected_result)
2509 mock_shuffle.assert_called_once_with(floating_ips)
2510 mock_find_floating_ip.assert_called_once_with(
2511 self.server, floating_ips, floating_network
2512 )
2514 @patch("random.shuffle")
2515 @patch.object(vimconnector, "_find_floating_ip")
2516 def test_get_free_floating_ip_list_floating_ip_exception(
2517 self, mock_find_floating_ip, mock_shuffle
2518 ):
2519 """Neutron list floating IPs raises exception."""
2520 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2521 self.vimconn.neutron = CopyingMock()
2522 self.vimconn.neutron.list_floatingips.side_effect = Exception(
2523 "Floating ips could not be listed."
2524 )
2525 with self.assertRaises(Exception) as err:
2526 result = self.vimconn._get_free_floating_ip(self.server, floating_network)
2527 self.assertEqual(result, None)
2528 self.assertEqual(str(err.exception), "Floating ips could not be listed.")
2529 mock_shuffle.assert_not_called()
2530 mock_find_floating_ip.assert_not_called()
2532 @patch("random.shuffle")
2533 @patch.object(vimconnector, "_find_floating_ip")
2534 def test_get_free_floating_ip_find_floating_ip_exception(
2535 self, mock_find_floating_ip, mock_shuffle
2536 ):
2537 """_find_floating_ip method raises exception."""
2538 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2539 floating_ips = [
2540 {
2541 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2542 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2543 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
2544 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
2545 },
2546 {
2547 "port_id": "508b73-r9cc-5a6a-5270-o2cc4811bd4a",
2548 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2549 "id": "208b73-o9cc-5a6a-a270-52cc4811bd8",
2550 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
2551 },
2552 ]
2553 self.vimconn.neutron = CopyingMock()
2554 self.vimconn.neutron.list_floatingips.return_value = {
2555 "floatingips": floating_ips
2556 }
2557 mock_find_floating_ip.side_effect = Exception(
2558 "Free floating ip could not be found."
2559 )
2561 with self.assertRaises(Exception) as err:
2562 result = self.vimconn._get_free_floating_ip(self.server, floating_network)
2563 self.assertEqual(result, None)
2564 self.assertEqual(str(err.exception), "Free floating ip could not be found.")
2565 mock_shuffle.assert_called_once_with(floating_ips)
2566 mock_find_floating_ip.assert_called_once_with(
2567 self.server, floating_ips, floating_network
2568 )
2570 @patch.object(vimconnector, "_create_floating_ip")
2571 @patch.object(vimconnector, "_get_free_floating_ip")
2572 @patch.object(vimconnector, "_assign_floating_ip")
2573 def test_prepare_external_network_for_vm_instance(
2574 self,
2575 mock_assign_floating_ip,
2576 mock_get_free_floating_ip,
2577 mock_create_floating_ip,
2578 ):
2579 """Prepare external network successfully."""
2580 external_network = [
2581 {
2582 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2583 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2584 },
2585 ]
2586 created_items = {}
2587 vm_start_time = time_return_value
2588 mock_get_free_floating_ip.side_effect = ["y08b73-o9cc-1a6a-a270-12cc4811bd4u"]
2589 mock_assign_floating_ip.return_value = {
2590 "floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}
2591 }
2592 self.vimconn.neutron = CopyingMock()
2593 self.vimconn.nova = CopyingMock()
2594 self.vimconn.neutron.show_floatingip.return_value = {
2595 "floatingip": {"port_id": ""}
2596 }
2598 self.vimconn._prepare_external_network_for_vminstance(
2599 external_network, self.server, created_items, vm_start_time
2600 )
2602 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
2603 mock_get_free_floating_ip.assert_called_once_with(
2604 self.server,
2605 {
2606 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2607 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2608 },
2609 )
2610 self.vimconn.neutron.show_floatingip.assert_called_once_with(
2611 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
2612 )
2613 self.vimconn.nova.servers.get.assert_not_called()
2614 mock_create_floating_ip.assert_not_called()
2615 mock_assign_floating_ip.assert_called_once_with(
2616 "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2617 {
2618 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2619 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2620 },
2621 )
2623 @patch("time.time")
2624 @patch("time.sleep")
2625 @patch.object(vimconnector, "_create_floating_ip")
2626 @patch.object(vimconnector, "_get_free_floating_ip")
2627 @patch.object(vimconnector, "_assign_floating_ip")
2628 def test_prepare_external_network_for_vm_instance_no_free_floating_ip(
2629 self,
2630 mock_assign_floating_ip,
2631 mock_get_free_floating_ip,
2632 mock_create_floating_ip,
2633 mock_sleep,
2634 mock_time,
2635 ):
2636 """There is not any free floating ip."""
2637 floating_network = {
2638 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2639 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2640 }
2641 external_network = [floating_network]
2643 created_items = {}
2644 vm_start_time = time_return_value
2645 mock_get_free_floating_ip.return_value = None
2646 mock_assign_floating_ip.return_value = {}
2647 self.vimconn.nova.servers.get.return_value.status = "ERROR"
2648 self.vimconn.neutron.show_floatingip.return_value = {}
2650 with self.assertRaises(KeyError):
2651 self.vimconn._prepare_external_network_for_vminstance(
2652 external_network, self.server, created_items, vm_start_time
2653 )
2655 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
2656 mock_get_free_floating_ip.assert_called_with(
2657 self.server,
2658 {
2659 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2660 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2661 },
2662 )
2663 self.vimconn.neutron.show_floatingip.assert_called_with(None)
2664 mock_sleep.assert_not_called()
2665 mock_time.assert_not_called()
2666 self.assertEqual(self.vimconn.nova.servers.get.call_count, 4)
2667 mock_create_floating_ip.assert_called_with(
2668 floating_network, self.server, created_items
2669 )
2670 self.assertEqual(mock_create_floating_ip.call_count, 4)
2671 mock_assign_floating_ip.assert_not_called()
2672 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
2674 @patch("time.time")
2675 @patch("time.sleep")
2676 @patch.object(vimconnector, "_create_floating_ip")
2677 @patch.object(vimconnector, "_get_free_floating_ip")
2678 @patch.object(vimconnector, "_assign_floating_ip")
2679 def test_prepare_external_network_for_vm_instance_no_free_fip_can_not_create_fip_exit_on_error_false(
2680 self,
2681 mock_assign_floating_ip,
2682 mock_get_free_floating_ip,
2683 mock_create_floating_ip,
2684 mock_sleep,
2685 mock_time,
2686 ):
2687 """There is not any free floating ip, create_floating ip method raise exception
2688 exit_on_floating_ip_error set to False."""
2689 floating_network = {
2690 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2691 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2692 "exit_on_floating_ip_error": False,
2693 }
2694 external_network = [floating_network]
2696 created_items = {}
2697 vm_start_time = time_return_value
2698 mock_get_free_floating_ip.return_value = None
2699 mock_assign_floating_ip.return_value = {}
2700 mock_create_floating_ip.side_effect = VimConnException(
2701 "Can not create floating ip."
2702 )
2703 self.vimconn.nova.servers.get.return_value.status = "ERROR"
2704 self.vimconn.neutron.show_floatingip.return_value = {}
2706 self.vimconn._prepare_external_network_for_vminstance(
2707 external_network, self.server, created_items, vm_start_time
2708 )
2709 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
2710 mock_get_free_floating_ip.assert_called_with(
2711 self.server,
2712 {
2713 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2714 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2715 "exit_on_floating_ip_error": False,
2716 },
2717 )
2718 self.vimconn.neutron.show_floatingip.assert_not_called()
2719 mock_sleep.assert_not_called()
2720 mock_time.assert_not_called()
2721 self.vimconn.nova.servers.get.assert_not_called()
2722 mock_create_floating_ip.assert_called_with(
2723 floating_network, self.server, created_items
2724 )
2725 self.assertEqual(mock_create_floating_ip.call_count, 1)
2726 mock_assign_floating_ip.assert_not_called()
2728 @patch("time.time")
2729 @patch("time.sleep")
2730 @patch.object(vimconnector, "_create_floating_ip")
2731 @patch.object(vimconnector, "_get_free_floating_ip")
2732 @patch.object(vimconnector, "_assign_floating_ip")
2733 def test_prepare_external_network_for_vm_instance_no_free_fip_can_not_create_fip_exit_on_error_true(
2734 self,
2735 mock_assign_floating_ip,
2736 mock_get_free_floating_ip,
2737 mock_create_floating_ip,
2738 mock_sleep,
2739 mock_time,
2740 ):
2741 """There is not any free floating ip, create_floating ip method raise exception
2742 exit_on_floating_ip_error set to False."""
2743 floating_network = {
2744 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2745 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2746 "exit_on_floating_ip_error": True,
2747 }
2748 external_network = [floating_network]
2750 created_items = {}
2751 vm_start_time = time_return_value
2752 mock_get_free_floating_ip.return_value = None
2753 mock_assign_floating_ip.return_value = {}
2754 mock_create_floating_ip.side_effect = VimConnException(
2755 "Can not create floating ip."
2756 )
2757 self.vimconn.nova.servers.get.return_value.status = "ERROR"
2758 self.vimconn.neutron.show_floatingip.return_value = {}
2759 with self.assertRaises(VimConnException):
2760 self.vimconn._prepare_external_network_for_vminstance(
2761 external_network, self.server, created_items, vm_start_time
2762 )
2763 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
2764 mock_get_free_floating_ip.assert_called_with(
2765 self.server,
2766 {
2767 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2768 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2769 "exit_on_floating_ip_error": True,
2770 },
2771 )
2772 self.vimconn.neutron.show_floatingip.assert_not_called()
2773 mock_sleep.assert_not_called()
2774 mock_time.assert_not_called()
2775 self.vimconn.nova.servers.get.assert_not_called()
2776 mock_create_floating_ip.assert_called_with(
2777 floating_network, self.server, created_items
2778 )
2779 self.assertEqual(mock_create_floating_ip.call_count, 1)
2780 mock_assign_floating_ip.assert_not_called()
2782 @patch.object(vimconnector, "_create_floating_ip")
2783 @patch.object(vimconnector, "_get_free_floating_ip")
2784 @patch.object(vimconnector, "_assign_floating_ip")
2785 def test_prepare_external_network_for_vm_instance_fip_has_port_id(
2786 self,
2787 mock_assign_floating_ip,
2788 mock_get_free_floating_ip,
2789 mock_create_floating_ip,
2790 ):
2791 """Neutron show floating ip return the fip with port_id and floating network vim_id
2792 is different from port_id."""
2793 floating_network = {
2794 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2795 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2796 }
2797 external_network = [floating_network]
2798 created_items = {}
2799 vm_start_time = 150
2800 mock_get_free_floating_ip.side_effect = [
2801 "t08b73-o9cc-1a6a-a270-12cc4811bd4u",
2802 "r08b73-o9cc-1a6a-a270-12cc4811bd4u",
2803 "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2804 ]
2805 mock_assign_floating_ip.side_effect = [
2806 {"floatingip": {"port_id": "k08b73-r9cc-5a6a-a270-82cc4811bd4a"}},
2807 {"floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}},
2808 ]
2809 self.vimconn.neutron = CopyingMock()
2810 self.vimconn.nova = CopyingMock()
2811 self.vimconn.neutron.show_floatingip.side_effect = [
2812 {"floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}},
2813 {"floatingip": {"port_id": ""}},
2814 {"floatingip": {"port_id": ""}},
2815 ]
2816 self.vimconn._prepare_external_network_for_vminstance(
2817 external_network, self.server, created_items, vm_start_time
2818 )
2819 self.assertEqual(mock_get_free_floating_ip.call_count, 3)
2820 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
2821 self.assertEqual(
2822 _call_mock_get_free_floating_ip[0][0],
2823 (
2824 self.server,
2825 floating_network,
2826 ),
2827 )
2828 self.assertEqual(
2829 _call_mock_get_free_floating_ip[1][0],
2830 (
2831 self.server,
2832 floating_network,
2833 ),
2834 )
2835 self.assertEqual(
2836 _call_mock_get_free_floating_ip[2][0],
2837 (
2838 self.server,
2839 floating_network,
2840 ),
2841 )
2842 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 3)
2843 self.vimconn.nova.servers.get.assert_not_called()
2844 mock_create_floating_ip.assert_not_called()
2845 self.assertEqual(mock_assign_floating_ip.call_count, 2)
2846 _call_mock_assign_floating_ip = mock_assign_floating_ip.call_args_list
2847 self.assertEqual(
2848 _call_mock_assign_floating_ip[0][0],
2849 ("r08b73-o9cc-1a6a-a270-12cc4811bd4u", floating_network),
2850 )
2851 self.assertEqual(
2852 _call_mock_assign_floating_ip[1][0],
2853 ("y08b73-o9cc-1a6a-a270-12cc4811bd4u", floating_network),
2854 )
2856 @patch("time.time")
2857 @patch("time.sleep")
2858 @patch.object(vimconnector, "_create_floating_ip")
2859 @patch.object(vimconnector, "_get_free_floating_ip")
2860 @patch.object(vimconnector, "_assign_floating_ip")
2861 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_vm_status_in_error(
2862 self,
2863 mock_assign_floating_ip,
2864 mock_get_free_floating_ip,
2865 mock_create_floating_ip,
2866 mock_sleep,
2867 mock_time,
2868 ):
2869 """Neutron show floating ip gives exception, exit_on_floating_ip_error set to True,
2870 VM status is in error."""
2871 floating_network = {
2872 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2873 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2874 "exit_on_floating_ip_error": True,
2875 }
2876 external_network = [floating_network]
2877 created_items = {}
2878 vm_start_time = time_return_value
2880 mock_time.side_effect = [156570150, 156570800, 156571200]
2882 self.vimconn.nova.servers.get.return_value.status = "ERROR"
2883 self.vimconn.neutron.show_floatingip.side_effect = [
2884 Exception("Floating ip could not be shown.")
2885 ] * 4
2886 with self.assertRaises(Exception) as err:
2887 self.vimconn._prepare_external_network_for_vminstance(
2888 external_network, self.server, created_items, vm_start_time
2889 )
2890 self.assertEqual(
2891 str(err.exception),
2892 "Cannot create floating_ip: Exception Floating ip could not be shown.",
2893 )
2895 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
2896 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
2897 self.assertEqual(
2898 _call_mock_get_free_floating_ip[0][0],
2899 (
2900 self.server,
2901 floating_network,
2902 ),
2903 )
2904 self.assertEqual(
2905 _call_mock_get_free_floating_ip[1][0],
2906 (
2907 self.server,
2908 floating_network,
2909 ),
2910 )
2911 self.assertEqual(
2912 _call_mock_get_free_floating_ip[2][0],
2913 (
2914 self.server,
2915 floating_network,
2916 ),
2917 )
2918 self.assertEqual(
2919 _call_mock_get_free_floating_ip[3][0],
2920 (
2921 self.server,
2922 floating_network,
2923 ),
2924 )
2926 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
2927 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
2928 mock_create_floating_ip.assert_not_called()
2929 mock_assign_floating_ip.assert_not_called()
2930 mock_time.assert_not_called()
2931 mock_sleep.assert_not_called()
2933 @patch("time.time")
2934 @patch("time.sleep")
2935 @patch.object(vimconnector, "_create_floating_ip")
2936 @patch.object(vimconnector, "_get_free_floating_ip")
2937 @patch.object(vimconnector, "_assign_floating_ip")
2938 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_vm_status_in_active(
2939 self,
2940 mock_assign_floating_ip,
2941 mock_get_free_floating_ip,
2942 mock_create_floating_ip,
2943 mock_sleep,
2944 mock_time,
2945 ):
2946 """Neutron show floating ip gives exception, exit_on_floating_ip_error is set to False,
2947 VM status is in active."""
2948 floating_network = {
2949 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
2950 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
2951 "exit_on_floating_ip_error": False,
2952 }
2953 external_network = [floating_network]
2954 created_items = {}
2955 vm_start_time = time_return_value
2957 mock_time.side_effect = [156570150, 156570800, 156571200]
2959 self.vimconn.nova.servers.get.return_value.status = "ACTIVE"
2960 self.vimconn.neutron.show_floatingip.side_effect = [
2961 Exception("Floating ip could not be shown.")
2962 ] * 4
2964 self.vimconn._prepare_external_network_for_vminstance(
2965 external_network, self.server, created_items, vm_start_time
2966 )
2967 # self.assertEqual(str(err.exception), "Cannot create floating_ip")
2969 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
2970 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
2971 self.assertEqual(
2972 _call_mock_get_free_floating_ip[0][0],
2973 (
2974 self.server,
2975 floating_network,
2976 ),
2977 )
2978 self.assertEqual(
2979 _call_mock_get_free_floating_ip[1][0],
2980 (
2981 self.server,
2982 floating_network,
2983 ),
2984 )
2985 self.assertEqual(
2986 _call_mock_get_free_floating_ip[2][0],
2987 (
2988 self.server,
2989 floating_network,
2990 ),
2991 )
2992 self.assertEqual(
2993 _call_mock_get_free_floating_ip[3][0],
2994 (
2995 self.server,
2996 floating_network,
2997 ),
2998 )
3000 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3001 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3002 mock_create_floating_ip.assert_not_called()
3003 mock_assign_floating_ip.assert_not_called()
3004 mock_time.assert_not_called()
3005 mock_sleep.assert_not_called()
3007 @patch("time.time")
3008 @patch("time.sleep")
3009 @patch.object(vimconnector, "_create_floating_ip")
3010 @patch.object(vimconnector, "_get_free_floating_ip")
3011 @patch.object(vimconnector, "_assign_floating_ip")
3012 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_exit_on_error(
3013 self,
3014 mock_assign_floating_ip,
3015 mock_get_free_floating_ip,
3016 mock_create_floating_ip,
3017 mock_sleep,
3018 mock_time,
3019 ):
3020 """Neutron show floating ip gives exception, but exit_on_floating_ip_error is set to True.
3021 VM status is not ACTIVE or ERROR, server timeout happened."""
3022 floating_network = {
3023 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3024 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3025 "exit_on_floating_ip_error": True,
3026 }
3027 external_network = [floating_network]
3028 created_items = {}
3029 vm_start_time = time_return_value
3030 mock_get_free_floating_ip.side_effect = None
3031 mock_time.side_effect = [156571790, 156571795, 156571800, 156571805]
3032 self.vimconn.nova.servers.get.return_value.status = "OTHER"
3033 self.vimconn.neutron.show_floatingip.side_effect = [
3034 Exception("Floating ip could not be shown.")
3035 ] * 5
3037 with self.assertRaises(VimConnException) as err:
3038 self.vimconn._prepare_external_network_for_vminstance(
3039 external_network, self.server, created_items, vm_start_time
3040 )
3041 self.assertEqual(
3042 str(err.exception),
3043 "Cannot create floating_ip: Exception Floating ip could not be shown.",
3044 )
3046 self.assertEqual(mock_get_free_floating_ip.call_count, 3)
3047 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3048 self.assertEqual(
3049 _call_mock_get_free_floating_ip[0][0],
3050 (
3051 self.server,
3052 floating_network,
3053 ),
3054 )
3055 self.assertEqual(
3056 _call_mock_get_free_floating_ip[1][0],
3057 (
3058 self.server,
3059 floating_network,
3060 ),
3061 )
3062 self.assertEqual(
3063 _call_mock_get_free_floating_ip[2][0],
3064 (
3065 self.server,
3066 floating_network,
3067 ),
3068 )
3070 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 3)
3071 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3072 mock_create_floating_ip.assert_not_called()
3073 mock_assign_floating_ip.assert_not_called()
3074 self.assertEqual(mock_time.call_count, 3)
3075 self.assertEqual(mock_sleep.call_count, 2)
3077 @patch("time.time")
3078 @patch("time.sleep")
3079 @patch.object(vimconnector, "_create_floating_ip")
3080 @patch.object(vimconnector, "_get_free_floating_ip")
3081 @patch.object(vimconnector, "_assign_floating_ip")
3082 def test_prepare_external_network_for_vm_instance_assign_floating_ip_exception_exit_on_error(
3083 self,
3084 mock_assign_floating_ip,
3085 mock_get_free_floating_ip,
3086 mock_create_floating_ip,
3087 mock_sleep,
3088 mock_time,
3089 ):
3090 """Assign floating ip method gives exception, exit_on_floating_ip_error is set to True.
3091 VM status is in ERROR."""
3092 floating_network = {
3093 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3094 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3095 "exit_on_floating_ip_error": True,
3096 }
3097 external_network = [floating_network]
3098 created_items = {}
3099 vm_start_time = time_return_value
3101 mock_get_free_floating_ip.side_effect = [
3102 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3103 ] * 4
3105 mock_time.side_effect = [156571790, 156571795, 156571800, 156571805]
3107 mock_assign_floating_ip.side_effect = [
3108 Exception("Floating ip could not be assigned.")
3109 ] * 4
3111 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3112 self.vimconn.neutron.show_floatingip.side_effect = [
3113 {"floatingip": {"port_id": ""}}
3114 ] * 4
3116 with self.assertRaises(VimConnException) as err:
3117 self.vimconn._prepare_external_network_for_vminstance(
3118 external_network, self.server, created_items, vm_start_time
3119 )
3120 self.assertEqual(
3121 str(err.exception),
3122 "Cannot create floating_ip: Exception Floating ip could not be assigned.",
3123 )
3125 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3126 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3127 self.assertEqual(
3128 _call_mock_get_free_floating_ip[0][0],
3129 (
3130 self.server,
3131 floating_network,
3132 ),
3133 )
3134 self.assertEqual(
3135 _call_mock_get_free_floating_ip[1][0],
3136 (
3137 self.server,
3138 floating_network,
3139 ),
3140 )
3141 self.assertEqual(
3142 _call_mock_get_free_floating_ip[2][0],
3143 (
3144 self.server,
3145 floating_network,
3146 ),
3147 )
3149 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3150 self.vimconn.neutron.show_floatingip.assert_called_with(
3151 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3152 )
3153 self.assertEqual(self.vimconn.nova.servers.get.call_count, 4)
3154 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3155 mock_time.assert_not_called()
3156 mock_sleep.assert_not_called()
3157 mock_create_floating_ip.assert_not_called()
3159 @patch("time.time")
3160 @patch("time.sleep")
3161 @patch.object(vimconnector, "_create_floating_ip")
3162 @patch.object(vimconnector, "_get_free_floating_ip")
3163 @patch.object(vimconnector, "_assign_floating_ip")
3164 def test_prepare_external_network_for_vm_instance_empty_external_network_list(
3165 self,
3166 mock_assign_floating_ip,
3167 mock_get_free_floating_ip,
3168 mock_create_floating_ip,
3169 mock_sleep,
3170 mock_time,
3171 ):
3172 """External network list is empty."""
3173 external_network = []
3174 created_items = {}
3175 vm_start_time = time_return_value
3177 self.vimconn._prepare_external_network_for_vminstance(
3178 external_network, self.server, created_items, vm_start_time
3179 )
3180 mock_create_floating_ip.assert_not_called()
3181 mock_time.assert_not_called()
3182 mock_sleep.assert_not_called()
3183 mock_assign_floating_ip.assert_not_called()
3184 mock_get_free_floating_ip.assert_not_called()
3185 self.vimconn.neutron.show.show_floatingip.assert_not_called()
3186 self.vimconn.nova.servers.get.assert_not_called()
3188 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3189 def test_update_port_security_for_vm_instance(self, mock_wait_for_vm):
3190 """no_secured_ports has port and the port has allow-address-pairs."""
3191 no_secured_ports = [(port2_id, "allow-address-pairs")]
3193 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3195 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3197 self.vimconn.neutron.update_port.assert_called_once_with(
3198 port2_id,
3199 {"port": {"allowed_address_pairs": [{"ip_address": "0.0.0.0/0"}]}},
3200 )
3202 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3203 def test_update_port_security_for_vm_instance_no_allowed_address_pairs(
3204 self, mock_wait_for_vm
3205 ):
3206 """no_secured_ports has port and the port does not have allow-address-pairs."""
3207 no_secured_ports = [(port2_id, "something")]
3209 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3211 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3213 self.vimconn.neutron.update_port.assert_called_once_with(
3214 port2_id,
3215 {"port": {"port_security_enabled": False, "security_groups": None}},
3216 )
3218 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3219 def test_update_port_security_for_vm_instance_wait_for_vm_raise_exception(
3220 self, mock_wait_for_vm
3221 ):
3222 """__wait_for_vm raises timeout exception."""
3223 no_secured_ports = [(port2_id, "something")]
3225 mock_wait_for_vm.side_effect = VimConnException("Timeout waiting for instance.")
3227 with self.assertRaises(VimConnException) as err:
3228 self.vimconn._update_port_security_for_vminstance(
3229 no_secured_ports, self.server
3230 )
3231 self.assertEqual(str(err.exception), "Timeout waiting for instance.")
3233 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3235 self.vimconn.neutron.update_port.assert_not_called()
3237 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3238 def test_update_port_security_for_vm_instance_neutron_update_port_raise_exception(
3239 self, mock_wait_for_vm
3240 ):
3241 """neutron_update_port method raises exception."""
3242 no_secured_ports = [(port2_id, "something")]
3244 self.vimconn.neutron.update_port.side_effect = Exception(
3245 "Port security could not be updated."
3246 )
3248 with self.assertRaises(VimConnException) as err:
3249 self.vimconn._update_port_security_for_vminstance(
3250 no_secured_ports, self.server
3251 )
3252 self.assertEqual(
3253 str(err.exception),
3254 "It was not possible to disable port security for port 17472685-f67f-49fd-8722-eabb7692fc22",
3255 )
3256 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3258 self.vimconn.neutron.update_port.assert_called_once_with(
3259 port2_id,
3260 {"port": {"port_security_enabled": False, "security_groups": None}},
3261 )
3263 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3264 def test_update_port_security_for_vm_instance_empty_port_list(
3265 self, mock_wait_for_vm
3266 ):
3267 """no_secured_ports list does not have any ports."""
3268 no_secured_ports = []
3270 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3272 mock_wait_for_vm.assert_not_called()
3274 self.vimconn.neutron.update_port.assert_not_called()
3276 @patch("time.time")
3277 @patch.object(vimconnector, "remove_keep_tag_from_persistent_volumes")
3278 @patch.object(vimconnector, "_reload_connection")
3279 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3280 @patch.object(vimconnector, "_create_user_data")
3281 @patch.object(vimconnector, "_get_vm_availability_zone")
3282 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3283 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3284 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3285 @patch.object(vimconnector, "delete_vminstance")
3286 @patch.object(vimconnector, "_format_exception")
3287 def test_new_vm_instance(
3288 self,
3289 mock_format_exception,
3290 mock_delete_vm_instance,
3291 mock_prepare_external_network,
3292 mock_update_port_security,
3293 mock_prepare_disk_for_vm_instance,
3294 mock_get_vm_availability_zone,
3295 mock_create_user_data,
3296 mock_prepare_network_for_vm_instance,
3297 mock_reload_connection,
3298 mock_remove_keep_flag_from_persistent_volumes,
3299 mock_time,
3300 ):
3301 """New VM instance creation is successful."""
3303 mock_create_user_data.return_value = True, "userdata"
3305 mock_get_vm_availability_zone.return_value = "nova"
3307 self.vimconn.nova.servers.create.return_value = self.server
3309 mock_time.return_value = time_return_value
3311 expected_result = self.server.id, {}
3313 result = self.vimconn.new_vminstance(
3314 name,
3315 description,
3316 start,
3317 image_id,
3318 flavor_id,
3319 affinity_group_list,
3320 net_list,
3321 cloud_config,
3322 disk_list2,
3323 availability_zone_index,
3324 availability_zone_list,
3325 security_group_name,
3326 )
3327 self.assertEqual(result, expected_result)
3329 mock_reload_connection.assert_called_once()
3330 mock_prepare_network_for_vm_instance.assert_called_once_with(
3331 name=name,
3332 net_list=net_list,
3333 created_items={},
3334 net_list_vim=[],
3335 external_network=[],
3336 no_secured_ports=[],
3337 security_group_name=security_group_name,
3338 )
3339 mock_create_user_data.assert_called_once_with(cloud_config)
3340 mock_get_vm_availability_zone.assert_called_once_with(
3341 availability_zone_index, availability_zone_list
3342 )
3343 mock_prepare_disk_for_vm_instance.assert_called_once_with(
3344 name=name,
3345 existing_vim_volumes=[],
3346 created_items={},
3347 storage_av_zone="nova",
3348 block_device_mapping={},
3349 disk_list=disk_list2,
3350 )
3351 self.vimconn.nova.servers.create.assert_called_once_with(
3352 name=name,
3353 image=image_id,
3354 flavor=flavor_id,
3355 nics=[],
3356 security_groups="default",
3357 availability_zone="nova",
3358 key_name="my_keypair",
3359 userdata="userdata",
3360 config_drive=True,
3361 block_device_mapping={},
3362 scheduler_hints={},
3363 )
3364 mock_time.assert_called_once()
3365 mock_update_port_security.assert_called_once_with([], self.server)
3366 mock_prepare_external_network.assert_called_once_with(
3367 external_network=[],
3368 server=self.server,
3369 created_items={},
3370 vm_start_time=time_return_value,
3371 )
3372 mock_remove_keep_flag_from_persistent_volumes.assert_not_called()
3373 mock_delete_vm_instance.assert_not_called()
3374 mock_format_exception.assert_not_called()
3376 @patch("time.time")
3377 @patch.object(vimconnector, "remove_keep_tag_from_persistent_volumes")
3378 @patch.object(vimconnector, "_reload_connection")
3379 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3380 @patch.object(vimconnector, "_create_user_data")
3381 @patch.object(vimconnector, "_get_vm_availability_zone")
3382 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3383 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3384 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3385 @patch.object(vimconnector, "delete_vminstance")
3386 @patch.object(vimconnector, "_format_exception")
3387 def test_new_vm_instance_create_user_data_fails(
3388 self,
3389 mock_format_exception,
3390 mock_delete_vm_instance,
3391 mock_prepare_external_network,
3392 mock_update_port_security,
3393 mock_prepare_disk_for_vm_instance,
3394 mock_get_vm_availability_zone,
3395 mock_create_user_data,
3396 mock_prepare_network_for_vm_instance,
3397 mock_reload_connection,
3398 mock_remove_keep_flag_from_persistent_volumes,
3399 mock_time,
3400 ):
3401 """New VM instance creation failed because of user data creation failure."""
3403 mock_create_user_data.side_effect = Exception(
3404 "User data could not be retrieved."
3405 )
3407 mock_get_vm_availability_zone.return_value = "nova"
3409 mock_remove_keep_flag_from_persistent_volumes.return_value = {}
3411 self.vimconn.nova.servers.create.return_value = self.server
3413 mock_time.return_value = time_return_value
3415 self.vimconn.new_vminstance(
3416 name,
3417 description,
3418 start,
3419 image_id,
3420 flavor_id,
3421 affinity_group_list,
3422 net_list,
3423 cloud_config,
3424 disk_list,
3425 availability_zone_index,
3426 availability_zone_list,
3427 security_group_name,
3428 )
3430 mock_reload_connection.assert_called_once()
3431 mock_prepare_network_for_vm_instance.assert_called_once_with(
3432 name=name,
3433 net_list=net_list,
3434 created_items={},
3435 net_list_vim=[],
3436 external_network=[],
3437 no_secured_ports=[],
3438 security_group_name=security_group_name,
3439 )
3440 mock_create_user_data.assert_called_once_with(cloud_config)
3441 mock_get_vm_availability_zone.assert_not_called()
3442 mock_prepare_disk_for_vm_instance.assert_not_called()
3443 self.vimconn.nova.servers.create.assert_not_called()
3444 mock_time.assert_not_called()
3445 mock_update_port_security.assert_not_called()
3446 mock_prepare_external_network.assert_not_called()
3447 mock_remove_keep_flag_from_persistent_volumes.assert_called_once_with({})
3448 mock_delete_vm_instance.assert_called_once_with(None, {})
3449 mock_format_exception.assert_called_once()
3450 arg = mock_format_exception.call_args[0][0]
3451 self.assertEqual(str(arg), "User data could not be retrieved.")
3453 @patch("time.time")
3454 @patch.object(vimconnector, "remove_keep_tag_from_persistent_volumes")
3455 @patch.object(vimconnector, "_reload_connection")
3456 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3457 @patch.object(vimconnector, "_create_user_data")
3458 @patch.object(vimconnector, "_get_vm_availability_zone")
3459 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3460 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3461 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3462 @patch.object(vimconnector, "delete_vminstance")
3463 @patch.object(vimconnector, "_format_exception")
3464 def test_new_vm_instance_external_network_exception(
3465 self,
3466 mock_format_exception,
3467 mock_delete_vm_instance,
3468 mock_prepare_external_network,
3469 mock_update_port_security,
3470 mock_prepare_disk_for_vm_instance,
3471 mock_get_vm_availability_zone,
3472 mock_create_user_data,
3473 mock_prepare_network_for_vm_instance,
3474 mock_reload_connection,
3475 mock_remove_keep_flag_from_persistent_volumes,
3476 mock_time,
3477 ):
3478 """New VM instance creation, external network connection has failed as floating
3479 ip could not be created."""
3481 mock_create_user_data.return_value = True, "userdata"
3483 mock_get_vm_availability_zone.return_value = "nova"
3485 self.vimconn.nova.servers.create.return_value = self.server
3487 mock_time.return_value = time_return_value
3489 mock_remove_keep_flag_from_persistent_volumes.return_value = {}
3491 mock_prepare_external_network.side_effect = VimConnException(
3492 "Can not create floating ip."
3493 )
3495 self.vimconn.new_vminstance(
3496 name,
3497 description,
3498 start,
3499 image_id,
3500 flavor_id,
3501 affinity_group_list,
3502 net_list,
3503 cloud_config,
3504 disk_list2,
3505 availability_zone_index,
3506 availability_zone_list,
3507 )
3509 mock_reload_connection.assert_called_once()
3510 mock_prepare_network_for_vm_instance.assert_called_once_with(
3511 name=name,
3512 net_list=net_list,
3513 created_items={},
3514 net_list_vim=[],
3515 external_network=[],
3516 no_secured_ports=[],
3517 security_group_name=security_group_name,
3518 )
3519 mock_create_user_data.assert_called_once_with(cloud_config)
3520 mock_get_vm_availability_zone.assert_called_once_with(
3521 availability_zone_index, availability_zone_list
3522 )
3523 mock_prepare_disk_for_vm_instance.assert_called_once_with(
3524 name=name,
3525 existing_vim_volumes=[],
3526 created_items={},
3527 storage_av_zone="nova",
3528 block_device_mapping={},
3529 disk_list=disk_list2,
3530 )
3531 self.vimconn.nova.servers.create.assert_called_once_with(
3532 name=name,
3533 image=image_id,
3534 flavor=flavor_id,
3535 nics=[],
3536 security_groups="default",
3537 availability_zone="nova",
3538 key_name="my_keypair",
3539 userdata="userdata",
3540 config_drive=True,
3541 block_device_mapping={},
3542 scheduler_hints={},
3543 )
3544 mock_time.assert_called_once()
3545 mock_update_port_security.assert_called_once_with([], self.server)
3546 mock_prepare_external_network.assert_called_once_with(
3547 external_network=[],
3548 server=self.server,
3549 created_items={},
3550 vm_start_time=time_return_value,
3551 )
3552 mock_remove_keep_flag_from_persistent_volumes.assert_called_once_with({})
3553 mock_delete_vm_instance.assert_called_once_with(self.server.id, {})
3554 mock_format_exception.assert_called_once()
3555 arg = mock_format_exception.call_args[0][0]
3556 self.assertEqual(str(arg), "Can not create floating ip.")
3558 @patch("time.time")
3559 @patch.object(vimconnector, "remove_keep_tag_from_persistent_volumes")
3560 @patch.object(vimconnector, "_reload_connection")
3561 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3562 @patch.object(vimconnector, "_create_user_data")
3563 @patch.object(vimconnector, "_get_vm_availability_zone")
3564 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3565 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3566 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3567 @patch.object(vimconnector, "delete_vminstance")
3568 @patch.object(vimconnector, "_format_exception")
3569 def test_new_vm_instance_with_affinity_group(
3570 self,
3571 mock_format_exception,
3572 mock_delete_vm_instance,
3573 mock_prepare_external_network,
3574 mock_update_port_security,
3575 mock_prepare_disk_for_vm_instance,
3576 mock_get_vm_availability_zone,
3577 mock_create_user_data,
3578 mock_prepare_network_for_vm_instance,
3579 mock_reload_connection,
3580 mock_remove_keep_flag_from_persistent_volumes,
3581 mock_time,
3582 ):
3583 """New VM creation with affinity group."""
3584 affinity_group_list = [
3585 {"affinity_group_id": "38b73-e9cc-5a6a-t270-82cc4811bd4a"}
3586 ]
3587 mock_create_user_data.return_value = True, "userdata"
3588 mock_get_vm_availability_zone.return_value = "nova"
3589 self.vimconn.nova.servers.create.return_value = self.server
3590 mock_time.return_value = time_return_value
3591 expected_result = self.server.id, {}
3593 result = self.vimconn.new_vminstance(
3594 name,
3595 description,
3596 start,
3597 image_id,
3598 flavor_id,
3599 affinity_group_list,
3600 net_list,
3601 cloud_config,
3602 disk_list2,
3603 availability_zone_index,
3604 availability_zone_list,
3605 security_group_name,
3606 )
3607 self.assertEqual(result, expected_result)
3609 mock_reload_connection.assert_called_once()
3610 mock_prepare_network_for_vm_instance.assert_called_once_with(
3611 name=name,
3612 net_list=net_list,
3613 created_items={},
3614 net_list_vim=[],
3615 external_network=[],
3616 no_secured_ports=[],
3617 security_group_name=security_group_name,
3618 )
3619 mock_create_user_data.assert_called_once_with(cloud_config)
3620 mock_get_vm_availability_zone.assert_called_once_with(
3621 availability_zone_index, availability_zone_list
3622 )
3623 mock_prepare_disk_for_vm_instance.assert_called_once_with(
3624 name=name,
3625 existing_vim_volumes=[],
3626 created_items={},
3627 storage_av_zone="nova",
3628 block_device_mapping={},
3629 disk_list=disk_list2,
3630 )
3631 self.vimconn.nova.servers.create.assert_called_once_with(
3632 name=name,
3633 image=image_id,
3634 flavor=flavor_id,
3635 nics=[],
3636 security_groups="default",
3637 availability_zone="nova",
3638 key_name="my_keypair",
3639 userdata="userdata",
3640 config_drive=True,
3641 block_device_mapping={},
3642 scheduler_hints={"group": "38b73-e9cc-5a6a-t270-82cc4811bd4a"},
3643 )
3644 mock_time.assert_called_once()
3645 mock_update_port_security.assert_called_once_with([], self.server)
3646 mock_prepare_external_network.assert_called_once_with(
3647 external_network=[],
3648 server=self.server,
3649 created_items={},
3650 vm_start_time=time_return_value,
3651 )
3652 mock_remove_keep_flag_from_persistent_volumes.assert_not_called()
3653 mock_delete_vm_instance.assert_not_called()
3654 mock_format_exception.assert_not_called()
3656 @patch("time.time")
3657 @patch.object(vimconnector, "remove_keep_tag_from_persistent_volumes")
3658 @patch.object(vimconnector, "_reload_connection")
3659 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3660 @patch.object(vimconnector, "_create_user_data")
3661 @patch.object(vimconnector, "_get_vm_availability_zone")
3662 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3663 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3664 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3665 @patch.object(vimconnector, "delete_vminstance")
3666 @patch.object(vimconnector, "_format_exception")
3667 def test_new_vm_instance_nova_server_create_failed(
3668 self,
3669 mock_format_exception,
3670 mock_delete_vm_instance,
3671 mock_prepare_external_network,
3672 mock_update_port_security,
3673 mock_prepare_disk_for_vm_instance,
3674 mock_get_vm_availability_zone,
3675 mock_create_user_data,
3676 mock_prepare_network_for_vm_instance,
3677 mock_reload_connection,
3678 mock_remove_keep_flag_from_persistent_volumes,
3679 mock_time,
3680 ):
3681 """New VM(server) creation failed."""
3683 mock_create_user_data.return_value = True, "userdata"
3685 mock_get_vm_availability_zone.return_value = "nova"
3687 self.vimconn.nova.servers.create.side_effect = Exception(
3688 "Server could not be created."
3689 )
3691 mock_time.return_value = time_return_value
3693 mock_remove_keep_flag_from_persistent_volumes.return_value = {}
3695 self.vimconn.new_vminstance(
3696 name,
3697 description,
3698 start,
3699 image_id,
3700 flavor_id,
3701 affinity_group_list,
3702 net_list,
3703 cloud_config,
3704 disk_list2,
3705 availability_zone_index,
3706 availability_zone_list,
3707 security_group_name,
3708 )
3710 mock_reload_connection.assert_called_once()
3711 mock_prepare_network_for_vm_instance.assert_called_once_with(
3712 name=name,
3713 net_list=net_list,
3714 created_items={},
3715 net_list_vim=[],
3716 external_network=[],
3717 no_secured_ports=[],
3718 security_group_name=security_group_name,
3719 )
3720 mock_create_user_data.assert_called_once_with(cloud_config)
3721 mock_get_vm_availability_zone.assert_called_once_with(
3722 availability_zone_index, availability_zone_list
3723 )
3724 mock_prepare_disk_for_vm_instance.assert_called_once_with(
3725 name=name,
3726 existing_vim_volumes=[],
3727 created_items={},
3728 storage_av_zone="nova",
3729 block_device_mapping={},
3730 disk_list=disk_list2,
3731 )
3733 self.vimconn.nova.servers.create.assert_called_once_with(
3734 name=name,
3735 image=image_id,
3736 flavor=flavor_id,
3737 nics=[],
3738 security_groups="default",
3739 availability_zone="nova",
3740 key_name="my_keypair",
3741 userdata="userdata",
3742 config_drive=True,
3743 block_device_mapping={},
3744 scheduler_hints={},
3745 )
3746 mock_time.assert_not_called()
3747 mock_update_port_security.assert_not_called()
3748 mock_prepare_external_network.assert_not_called()
3749 mock_remove_keep_flag_from_persistent_volumes.assert_called_once_with({})
3750 mock_delete_vm_instance.assert_called_once_with(None, {})
3751 mock_format_exception.assert_called_once()
3752 arg = mock_format_exception.call_args[0][0]
3753 self.assertEqual(str(arg), "Server could not be created.")
3755 @patch("time.time")
3756 @patch.object(vimconnector, "remove_keep_tag_from_persistent_volumes")
3757 @patch.object(vimconnector, "_reload_connection")
3758 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3759 @patch.object(vimconnector, "_create_user_data")
3760 @patch.object(vimconnector, "_get_vm_availability_zone")
3761 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3762 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3763 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3764 @patch.object(vimconnector, "delete_vminstance")
3765 @patch.object(vimconnector, "_format_exception")
3766 def test_new_vm_instance_connection_exception(
3767 self,
3768 mock_format_exception,
3769 mock_delete_vm_instance,
3770 mock_prepare_external_network,
3771 mock_update_port_security,
3772 mock_prepare_disk_for_vm_instance,
3773 mock_get_vm_availability_zone,
3774 mock_create_user_data,
3775 mock_prepare_network_for_vm_instance,
3776 mock_reload_connection,
3777 mock_remove_keep_flag_from_persistent_volumes,
3778 mock_time,
3779 ):
3780 """Connection to Cloud API has failed."""
3781 mock_reload_connection.side_effect = Exception("Can not connect to Cloud APIs.")
3782 mock_create_user_data.return_value = True, "userdata"
3783 mock_get_vm_availability_zone.return_value = "nova"
3784 self.vimconn.nova.servers.create.return_value = self.server
3785 mock_time.return_value = time_return_value
3786 mock_remove_keep_flag_from_persistent_volumes.return_value = {}
3788 self.vimconn.new_vminstance(
3789 name,
3790 description,
3791 start,
3792 image_id,
3793 flavor_id,
3794 affinity_group_list,
3795 net_list,
3796 cloud_config,
3797 disk_list,
3798 availability_zone_index,
3799 availability_zone_list,
3800 )
3801 mock_format_exception.assert_called_once()
3802 arg = mock_format_exception.call_args[0][0]
3803 self.assertEqual(str(arg), "Can not connect to Cloud APIs.")
3804 mock_reload_connection.assert_called_once()
3805 mock_prepare_network_for_vm_instance.assert_not_called()
3806 mock_create_user_data.assert_not_called()
3807 mock_get_vm_availability_zone.assert_not_called()
3808 mock_prepare_disk_for_vm_instance.assert_not_called()
3809 self.vimconn.nova.servers.create.assert_not_called()
3810 mock_time.assert_not_called()
3811 mock_update_port_security.assert_not_called()
3812 mock_prepare_external_network.assert_not_called()
3813 mock_remove_keep_flag_from_persistent_volumes.assert_called_once_with({})
3814 mock_delete_vm_instance.assert_called_once_with(None, {})
3816 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
3817 def test_delete_vm_ports_attached_to_network_empty_created_items(
3818 self, mock_delete_ports_by_id_wth_neutron
3819 ):
3820 """Created_items is emtpty."""
3821 created_items = {}
3822 self.vimconn._delete_vm_ports_attached_to_network(created_items)
3823 self.vimconn.neutron.list_ports.assert_not_called()
3824 self.vimconn.neutron.delete_port.assert_not_called()
3825 mock_delete_ports_by_id_wth_neutron.assert_not_called()
3827 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
3828 def test_delete_vm_ports_attached_to_network(
3829 self, mock_delete_ports_by_id_wth_neutron
3830 ):
3831 created_items = {
3832 "floating_ip:308b73-t9cc-1a6a-a270-12cc4811bd4a": True,
3833 f"volume:{volume_id2}": True,
3834 f"volume:{volume_id}": True,
3835 f"port:{port_id}": True,
3836 }
3837 self.vimconn._delete_vm_ports_attached_to_network(created_items)
3838 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}")
3839 self.vimconn.logger.error.assert_not_called()
3841 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
3842 def test_delete_vm_ports_attached_to_network_wthout_port(
3843 self, mock_delete_ports_by_id_wth_neutron
3844 ):
3845 """Created_items does not have port."""
3846 created_items = {
3847 f"floating_ip:{floating_network_vim_id}": True,
3848 f"volume:{volume_id2}": True,
3849 f"volume:{volume_id}": True,
3850 }
3851 self.vimconn._delete_vm_ports_attached_to_network(created_items)
3852 mock_delete_ports_by_id_wth_neutron.assert_not_called()
3853 self.vimconn.logger.error.assert_not_called()
3855 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
3856 def test_delete_vm_ports_attached_to_network_delete_port_raise_vimconnexception(
3857 self, mock_delete_ports_by_id_wth_neutron
3858 ):
3859 """_delete_ports_by_id_wth_neutron raises vimconnexception."""
3860 created_items = deepcopy(created_items_all_true)
3861 mock_delete_ports_by_id_wth_neutron.side_effect = VimConnException(
3862 "Can not delete port"
3863 )
3864 self.vimconn._delete_vm_ports_attached_to_network(created_items)
3865 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}")
3866 self.vimconn.logger.error.assert_called_once_with(
3867 "Error deleting port: VimConnException: Can not delete port"
3868 )
3870 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
3871 def test_delete_vm_ports_attached_to_network_delete_port_raise_nvexception(
3872 self, mock_delete_ports_by_id_wth_neutron
3873 ):
3874 """_delete_ports_by_id_wth_neutron raises nvExceptions.ClientException."""
3875 created_items = deepcopy(created_items_all_true)
3876 mock_delete_ports_by_id_wth_neutron.side_effect = nvExceptions.ClientException(
3877 "Connection aborted."
3878 )
3879 self.vimconn._delete_vm_ports_attached_to_network(created_items)
3880 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}")
3881 self.vimconn.logger.error.assert_called_once_with(
3882 "Error deleting port: ClientException: Unknown Error (HTTP Connection aborted.)"
3883 )
3885 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
3886 def test_delete_vm_ports_attached_to_network_delete_port_invalid_port_item(
3887 self, mock_delete_ports_by_id_wth_neutron
3888 ):
3889 """port item is invalid."""
3890 created_items = {
3891 f"floating_ip:{floating_network_vim_id}": True,
3892 f"volume:{volume_id2}": True,
3893 f"volume:{volume_id}": True,
3894 f"port:{port_id}:": True,
3895 }
3896 mock_delete_ports_by_id_wth_neutron.side_effect = VimConnException(
3897 "Port is not valid."
3898 )
3899 self.vimconn._delete_vm_ports_attached_to_network(created_items)
3900 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}:")
3901 self.vimconn.logger.error.assert_called_once_with(
3902 "Error deleting port: VimConnException: Port is not valid."
3903 )
3905 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
3906 def test_delete_vm_ports_attached_to_network_delete_port_already_deleted(
3907 self, mock_delete_ports_by_id_wth_neutron
3908 ):
3909 """port is already deleted."""
3910 created_items = {
3911 f"floating_ip:{floating_network_vim_id}": True,
3912 f"volume:{volume_id2}": True,
3913 f"volume:{volume_id}": None,
3914 f"port:{port_id}": None,
3915 }
3916 self.vimconn._delete_vm_ports_attached_to_network(created_items)
3917 mock_delete_ports_by_id_wth_neutron.assert_not_called()
3918 self.vimconn.logger.error.assert_not_called()
3920 def test_delete_floating_ip_by_id(self):
3921 created_items = {
3922 f"floating_ip:{floating_network_vim_id}": True,
3923 f"port:{port_id}": True,
3924 }
3925 expected_created_items = {
3926 f"floating_ip:{floating_network_vim_id}": None,
3927 f"port:{port_id}": True,
3928 }
3929 k_id = floating_network_vim_id
3930 k = f"floating_ip:{floating_network_vim_id}"
3931 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
3932 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
3933 self.assertEqual(created_items, expected_created_items)
3935 def test_delete_floating_ip_by_id_floating_ip_already_deleted(self):
3936 """floating ip is already deleted."""
3937 created_items = {
3938 f"floating_ip:{floating_network_vim_id}": None,
3939 f"port:{port_id}": True,
3940 }
3941 k_id = floating_network_vim_id
3942 k = f"floating_ip:{floating_network_vim_id}"
3943 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
3944 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
3945 self.assertEqual(
3946 created_items,
3947 {
3948 f"floating_ip:{floating_network_vim_id}": None,
3949 f"port:{port_id}": True,
3950 },
3951 )
3953 def test_delete_floating_ip_by_id__delete_floating_ip_raises_client_exception__operation_is_successful(
3954 self,
3955 ):
3956 """netron delete floating ip raises nvExceptions.ClientException."""
3957 created_items = {
3958 f"floating_ip:{floating_network_vim_id}": True,
3959 f"port:{port_id}": True,
3960 }
3961 k_id = floating_network_vim_id
3962 k = f"floating_ip:{floating_network_vim_id}"
3963 self.vimconn.neutron.delete_floatingip.side_effect = (
3964 nvExceptions.ClientException("Client exception occurred.")
3965 )
3966 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
3967 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
3968 self.assertEqual(
3969 created_items,
3970 {
3971 f"floating_ip:{floating_network_vim_id}": True,
3972 f"port:{port_id}": True,
3973 },
3974 )
3975 self.vimconn.logger.error.assert_called_once_with(
3976 "Error deleting floating ip: ClientException: Unknown Error (HTTP Client exception occurred.)"
3977 )
3979 def test_delete_floating_ip_by_id__delete_floating_ip_raises_connection_error__operation_fails(
3980 self,
3981 ):
3982 """netron delete floating ip raises nvExceptions.ClientException."""
3983 created_items = {
3984 f"floating_ip:{floating_network_vim_id}": True,
3985 f"port:{port_id}": True,
3986 }
3987 k_id = floating_network_vim_id
3988 k = f"floating_ip:{floating_network_vim_id}"
3989 self.vimconn.neutron.delete_floatingip.side_effect = ConnectionError(
3990 "Connection exception occurred."
3991 )
3992 with self.assertRaises(VimConnConnectionException):
3993 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
3994 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
3995 self.assertEqual(
3996 created_items,
3997 {
3998 f"floating_ip:{floating_network_vim_id}": True,
3999 f"port:{port_id}": True,
4000 },
4001 )
4002 self.vimconn.logger.error.assert_called_once_with(
4003 "Error deleting floating ip: ConnectionError: Connection exception occurred."
4004 )
4006 def test_delete_floating_ip_by_id_floating_ip_raises_vimconn_not_found_exception__operation_is_successful(
4007 self,
4008 ):
4009 """netron delete floating ip raises VimConnNotFoundException."""
4010 created_items = {
4011 f"floating_ip:{floating_network_vim_id}": True,
4012 f"port:{port_id}": True,
4013 }
4014 k_id = floating_network_vim_id
4015 k = f"floating_ip:{floating_network_vim_id}"
4016 self.vimconn.neutron.delete_floatingip.side_effect = VimConnNotFoundException(
4017 "Port id could not found."
4018 )
4019 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
4020 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
4021 self.assertEqual(
4022 created_items,
4023 {
4024 f"floating_ip:{floating_network_vim_id}": True,
4025 f"port:{port_id}": True,
4026 },
4027 )
4028 self.vimconn.logger.error.assert_called_once_with(
4029 "Error deleting floating ip: VimConnNotFoundException: Port id could not found."
4030 )
4032 def test_delete_floating_ip_by_id_floating_ip_invalid_k_item(self):
4033 """invalid floating ip item."""
4034 created_items = {
4035 f"floating_ip:{floating_network_vim_id}": True,
4036 f"port:{port_id}": True,
4037 }
4038 expected_created_items = {
4039 f"floating_ip:{floating_network_vim_id}::": None,
4040 f"floating_ip:{floating_network_vim_id}": True,
4041 f"port:{port_id}": True,
4042 }
4043 k_id = floating_network_vim_id
4044 k = f"floating_ip:{floating_network_vim_id}::"
4045 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
4046 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
4047 self.assertEqual(created_items, expected_created_items)
4049 def test_delete_volumes_by_id_with_cinder_volume_status_available(self):
4050 """volume status is available."""
4051 created_items = {
4052 f"floating_ip:{floating_network_vim_id}": True,
4053 f"volume:{volume_id2}": True,
4054 f"volume:{volume_id}": True,
4055 f"port:{port_id}": None,
4056 }
4057 expected_created_items = {
4058 f"floating_ip:{floating_network_vim_id}": True,
4059 f"volume:{volume_id2}": True,
4060 f"volume:{volume_id}": None,
4061 f"port:{port_id}": None,
4062 }
4063 volumes_to_hold = []
4064 k = f"volume:{volume_id}"
4065 k_id = volume_id
4066 self.vimconn.cinder.volumes.get.return_value.status = "available"
4067 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4068 k, k_id, volumes_to_hold, created_items
4069 )
4070 self.assertEqual(result, None)
4071 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4072 self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
4073 self.vimconn.logger.error.assert_not_called()
4074 self.assertEqual(created_items, expected_created_items)
4076 def test_delete_volumes_by_id_with_cinder_volume_already_deleted(self):
4077 """volume is already deleted."""
4078 created_items = {
4079 f"floating_ip:{floating_network_vim_id}": True,
4080 f"volume:{volume_id2}": True,
4081 f"volume:{volume_id}": None,
4082 f"port:{port_id}": None,
4083 }
4084 expected_created_items = {
4085 f"floating_ip:{floating_network_vim_id}": True,
4086 f"volume:{volume_id2}": True,
4087 f"volume:{volume_id}": None,
4088 f"port:{port_id}": None,
4089 }
4090 volumes_to_hold = []
4091 k = f"volume:{volume_id}"
4092 k_id = volume_id
4093 self.vimconn.cinder.volumes.get.return_value.status = "available"
4094 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4095 k, k_id, volumes_to_hold, created_items
4096 )
4097 self.assertEqual(result, None)
4098 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4099 self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
4100 self.vimconn.logger.error.assert_not_called()
4101 self.assertEqual(created_items, expected_created_items)
4103 def test_delete_shared_volumes(self):
4104 """cinder delete shared volumes"""
4105 shared_volume_vim_id = volume_id4
4106 self.vimconn.cinder.volumes.get.return_value.status = "available"
4107 self.vimconn.delete_shared_volumes(shared_volume_vim_id)
4108 self.vimconn.cinder.volumes.get.assert_called_once_with(shared_volume_vim_id)
4109 self.vimconn.cinder.volumes.delete.assert_called_once_with(shared_volume_vim_id)
4110 self.vimconn.logger.error.assert_not_called()
4112 def test_delete_volumes_by_id_with_cinder_get_volume_raise_exception(self):
4113 """cinder get volume raises exception."""
4114 created_items = {
4115 f"floating_ip:{floating_network_vim_id}": True,
4116 f"volume:{volume_id2}": True,
4117 f"volume:{volume_id}": True,
4118 f"port:{port_id}": None,
4119 }
4120 expected_created_items = {
4121 f"floating_ip:{floating_network_vim_id}": True,
4122 f"volume:{volume_id2}": True,
4123 f"volume:{volume_id}": True,
4124 f"port:{port_id}": None,
4125 }
4126 volumes_to_hold = []
4127 k = f"volume:{volume_id}"
4128 k_id = volume_id
4129 self.vimconn.cinder.volumes.get.side_effect = Exception(
4130 "Can not get volume status."
4131 )
4132 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4133 k, k_id, volumes_to_hold, created_items
4134 )
4135 self.assertEqual(result, None)
4136 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4137 self.vimconn.cinder.volumes.delete.assert_not_called()
4138 self.vimconn.logger.error.assert_called_once_with(
4139 "Error deleting volume: Exception: Can not get volume status."
4140 )
4141 self.assertEqual(created_items, expected_created_items)
4143 def test_delete_volumes_by_id_with_cinder__delete_volume_raise_client_exception__exception_is_not_raised(
4144 self,
4145 ):
4146 """cinder delete volume raises exception."""
4147 created_items = {
4148 f"floating_ip:{floating_network_vim_id}": True,
4149 f"volume:{volume_id2}": True,
4150 f"volume:{volume_id}": True,
4151 f"port:{port_id}": None,
4152 }
4153 expected_created_items = {
4154 f"floating_ip:{floating_network_vim_id}": True,
4155 f"volume:{volume_id2}": True,
4156 f"volume:{volume_id}": True,
4157 f"port:{port_id}": None,
4158 }
4159 volumes_to_hold = []
4160 k = f"volume:{volume_id}"
4161 k_id = volume_id
4162 self.vimconn.cinder.volumes.get.return_value.status = "available"
4163 self.vimconn.cinder.volumes.delete.side_effect = cExceptions.ClientException(
4164 403, "Connection aborted."
4165 )
4166 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4167 k, k_id, volumes_to_hold, created_items
4168 )
4169 self.assertEqual(result, None)
4170 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4171 self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
4172 self.vimconn.logger.error.assert_called_once_with(
4173 "Error deleting volume: ClientException: Connection aborted. (HTTP 403)"
4174 )
4175 self.assertEqual(created_items, expected_created_items)
4177 def test_delete_volumes_by_id_with_cinder__delete_volume_raise_connection_exception__exception_is_raised(
4178 self,
4179 ):
4180 """cinder delete volume raises exception."""
4181 created_items = {
4182 f"floating_ip:{floating_network_vim_id}": True,
4183 f"volume:{volume_id2}": True,
4184 f"volume:{volume_id}": True,
4185 f"port:{port_id}": None,
4186 }
4187 expected_created_items = {
4188 f"floating_ip:{floating_network_vim_id}": True,
4189 f"volume:{volume_id2}": True,
4190 f"volume:{volume_id}": True,
4191 f"port:{port_id}": None,
4192 }
4193 volumes_to_hold = []
4194 k = f"volume:{volume_id}"
4195 k_id = volume_id
4196 self.vimconn.cinder.volumes.get.return_value.status = "available"
4197 self.vimconn.cinder.volumes.delete.side_effect = cExceptions.ConnectionError(
4198 "Connection failed."
4199 )
4200 with self.assertRaises(VimConnConnectionException):
4201 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4202 k, k_id, volumes_to_hold, created_items
4203 )
4204 self.assertEqual(result, None)
4205 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4206 self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
4207 self.vimconn.logger.error.assert_called_once_with(
4208 "Error deleting volume: ConnectionError: Connection failed."
4209 )
4210 self.assertEqual(created_items, expected_created_items)
4212 def test_delete_volumes_by_id_with_cinder_volume_to_be_hold(self):
4213 """volume_to_hold has item."""
4214 created_items = {
4215 f"floating_ip:{floating_network_vim_id}": True,
4216 f"volume:{volume_id2}": True,
4217 f"volume:{volume_id}": True,
4218 f"port:{port_id}": None,
4219 }
4220 expected_created_items = {
4221 f"floating_ip:{floating_network_vim_id}": True,
4222 f"volume:{volume_id2}": True,
4223 f"volume:{volume_id}": True,
4224 f"port:{port_id}": None,
4225 }
4226 volumes_to_hold = [volume_id]
4227 k = f"volume:{volume_id}"
4228 k_id = volume_id
4229 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4230 k, k_id, volumes_to_hold, created_items
4231 )
4232 self.assertEqual(result, False)
4233 self.vimconn.cinder.volumes.get.assert_not_called()
4234 self.vimconn.cinder.volumes.delete.assert_not_called()
4235 self.vimconn.logger.error.assert_not_called()
4236 self.assertEqual(created_items, expected_created_items)
4238 def test_delete_volumes_by_id_with_cinder_volume_status_not_available(self):
4239 """volume status is not available."""
4240 created_items = {
4241 f"floating_ip:{floating_network_vim_id}": True,
4242 f"volume:{volume_id2}": True,
4243 f"volume:{volume_id}": True,
4244 f"port:{port_id}": None,
4245 }
4246 expected_created_items = {
4247 f"floating_ip:{floating_network_vim_id}": True,
4248 f"volume:{volume_id2}": True,
4249 f"volume:{volume_id}": True,
4250 f"port:{port_id}": None,
4251 }
4252 volumes_to_hold = []
4253 k = f"volume:{volume_id}"
4254 k_id = volume_id
4255 self.vimconn.cinder.volumes.get.return_value.status = "unavailable"
4256 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4257 k, k_id, volumes_to_hold, created_items
4258 )
4259 self.assertEqual(result, True)
4260 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4261 self.vimconn.cinder.volumes.delete.assert_not_called()
4262 self.vimconn.logger.error.assert_not_called()
4263 self.assertEqual(created_items, expected_created_items)
4265 def test_delete_ports_by_id_by_neutron(self):
4266 """neutron delete ports."""
4267 k_id = port_id
4268 self.vimconn._delete_ports_by_id_wth_neutron(k_id)
4269 self.vimconn.neutron.delete_port.assert_called_once_with(k_id)
4270 self.vimconn.logger.error.assert_not_called()
4272 def test_delete_ports_by_id_by_neutron_delete_port_raise_exception(self):
4273 """neutron delete port raises exception."""
4274 k_id = port_id
4275 self.vimconn.neutron.delete_port.side_effect = nvExceptions.ClientException(
4276 "Connection aborted."
4277 )
4278 self.vimconn._delete_ports_by_id_wth_neutron(k_id)
4279 self.vimconn.neutron.delete_port.assert_called_once_with(k_id)
4280 self.vimconn.logger.error.assert_called_once_with(
4281 "Error deleting port: ClientException: Unknown Error (HTTP Connection aborted.)"
4282 )
4284 def test_get_item_name_id(self):
4285 """Get name and id successfully."""
4286 k = f"some:{port_id}"
4287 result = self.vimconn._get_item_name_id(k)
4288 self.assertEqual(result, ("some", f"{port_id}"))
4290 def test_get_item_name_id_wthout_semicolon(self):
4291 """Does not have seperator."""
4292 k = f"some{port_id}"
4293 result = self.vimconn._get_item_name_id(k)
4294 self.assertEqual(result, (f"some{port_id}", ""))
4296 def test_get_item_name_id_empty_string(self):
4297 """Empty string."""
4298 k = ""
4299 result = self.vimconn._get_item_name_id(k)
4300 self.assertEqual(result, ("", ""))
4302 def test_get_item_name_id_k_is_none(self):
4303 """item is None."""
4304 k = None
4305 with self.assertRaises(AttributeError):
4306 self.vimconn._get_item_name_id(k)
4308 @patch.object(vimconnector, "_get_item_name_id")
4309 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4310 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4311 def test_delete_created_items(
4312 self,
4313 mock_delete_floating_ip_by_id,
4314 mock_delete_volumes_by_id_wth_cinder,
4315 mock_get_item_name_id,
4316 ):
4317 """Created items has floating ip and volume."""
4318 created_items = {
4319 f"floating_ip:{floating_network_vim_id}": True,
4320 f"volume:{volume_id}": True,
4321 f"port:{port_id}": None,
4322 }
4323 mock_get_item_name_id.side_effect = [
4324 ("floating_ip", f"{floating_network_vim_id}"),
4325 ("volume", f"{volume_id}"),
4326 ]
4327 mock_delete_volumes_by_id_wth_cinder.return_value = True
4328 volumes_to_hold = []
4329 keep_waiting = False
4330 result = self.vimconn._delete_created_items(
4331 created_items, volumes_to_hold, keep_waiting
4332 )
4333 self.assertEqual(result, True)
4334 self.assertEqual(mock_get_item_name_id.call_count, 2)
4335 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
4336 f"volume:{volume_id}", f"{volume_id}", [], created_items
4337 )
4338 mock_delete_floating_ip_by_id.assert_called_once_with(
4339 f"floating_ip:{floating_network_vim_id}",
4340 f"{floating_network_vim_id}",
4341 created_items,
4342 )
4343 self.vimconn.logger.error.assert_not_called()
4345 @patch.object(vimconnector, "_get_item_name_id")
4346 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4347 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4348 def test_delete_created_items_wth_volumes_to_hold(
4349 self,
4350 mock_delete_floating_ip_by_id,
4351 mock_delete_volumes_by_id_wth_cinder,
4352 mock_get_item_name_id,
4353 ):
4354 """Created items has floating ip and volume and volumes_to_hold has items."""
4355 created_items = {
4356 f"floating_ip:{floating_network_vim_id}": True,
4357 f"volume:{volume_id}": True,
4358 f"port:{port_id}": None,
4359 }
4360 mock_get_item_name_id.side_effect = [
4361 ("floating_ip", f"{floating_network_vim_id}"),
4362 ("volume", f"{volume_id}"),
4363 ]
4364 mock_delete_volumes_by_id_wth_cinder.return_value = True
4365 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4366 keep_waiting = False
4367 result = self.vimconn._delete_created_items(
4368 created_items, volumes_to_hold, keep_waiting
4369 )
4370 self.assertEqual(result, True)
4371 self.assertEqual(mock_get_item_name_id.call_count, 2)
4372 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
4373 f"volume:{volume_id}", f"{volume_id}", volumes_to_hold, created_items
4374 )
4375 mock_delete_floating_ip_by_id.assert_called_once_with(
4376 f"floating_ip:{floating_network_vim_id}",
4377 f"{floating_network_vim_id}",
4378 created_items,
4379 )
4380 self.vimconn.logger.error.assert_not_called()
4382 @patch.object(vimconnector, "_get_item_name_id")
4383 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4384 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4385 def test_delete_created_items_wth_keep_waiting_true(
4386 self,
4387 mock_delete_floating_ip_by_id,
4388 mock_delete_volumes_by_id_wth_cinder,
4389 mock_get_item_name_id,
4390 ):
4391 """Keep waiting initial value is True."""
4392 created_items = {
4393 f"floating_ip:{floating_network_vim_id}": True,
4394 f"volume:{volume_id}": True,
4395 f"port:{port_id}": None,
4396 }
4397 mock_get_item_name_id.side_effect = [
4398 ("floating_ip", f"{floating_network_vim_id}"),
4399 ("volume", f"{volume_id}"),
4400 ]
4401 mock_delete_volumes_by_id_wth_cinder.return_value = False
4402 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4403 keep_waiting = True
4404 result = self.vimconn._delete_created_items(
4405 created_items, volumes_to_hold, keep_waiting
4406 )
4407 self.assertEqual(result, True)
4408 self.assertEqual(mock_get_item_name_id.call_count, 2)
4409 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
4410 f"volume:{volume_id}", f"{volume_id}", volumes_to_hold, created_items
4411 )
4412 mock_delete_floating_ip_by_id.assert_called_once_with(
4413 f"floating_ip:{floating_network_vim_id}",
4414 f"{floating_network_vim_id}",
4415 created_items,
4416 )
4417 self.vimconn.logger.error.assert_not_called()
4419 @patch.object(vimconnector, "_get_item_name_id")
4420 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4421 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4422 def test_delete_created_items__delete_vol_raises_connection_error__operation_fails(
4423 self,
4424 mock_delete_floating_ip_by_id,
4425 mock_delete_volumes_by_id_wth_cinder,
4426 mock_get_item_name_id,
4427 ):
4428 """Delete volume raises exception."""
4429 created_items = {
4430 f"floating_ip:{floating_network_vim_id}": True,
4431 f"volume:{volume_id}": True,
4432 f"port:{port_id}": None,
4433 }
4434 mock_get_item_name_id.side_effect = [
4435 ("floating_ip", f"{floating_network_vim_id}"),
4436 ("volume", f"{volume_id}"),
4437 ]
4438 mock_delete_volumes_by_id_wth_cinder.side_effect = (
4439 neExceptions.ConnectionFailed("Connection failed.")
4440 )
4441 volumes_to_hold = []
4442 keep_waiting = False
4443 with self.assertRaises(VimConnConnectionException):
4444 result = self.vimconn._delete_created_items(
4445 created_items, volumes_to_hold, keep_waiting
4446 )
4447 self.assertEqual(result, None)
4448 self.assertEqual(mock_get_item_name_id.call_count, 2)
4449 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
4450 f"volume:{volume_id}", f"{volume_id}", [], created_items
4451 )
4452 mock_delete_floating_ip_by_id.assert_called_once_with(
4453 f"floating_ip:{floating_network_vim_id}",
4454 f"{floating_network_vim_id}",
4455 created_items,
4456 )
4457 self.vimconn.logger.error.assert_called_once_with(
4458 "Error deleting volume:ac408b73-b9cc-4a6a-a270-82cc4811bd4a: Connection failed."
4459 )
4461 @patch.object(vimconnector, "_get_item_name_id")
4462 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4463 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4464 def test_delete_created_items__delete_fip_raises_connection_error__operation_fails(
4465 self,
4466 mock_delete_floating_ip_by_id,
4467 mock_delete_volumes_by_id_wth_cinder,
4468 mock_get_item_name_id,
4469 ):
4470 """Delete floating ip raises exception."""
4471 created_items = {
4472 f"floating_ip:{floating_network_vim_id}": True,
4473 f"volume:{volume_id}": True,
4474 f"port:{port_id}": None,
4475 }
4476 mock_get_item_name_id.side_effect = [
4477 ("floating_ip", f"{floating_network_vim_id}"),
4478 ("volume", f"{volume_id}"),
4479 ]
4480 mock_delete_volumes_by_id_wth_cinder.return_value = False
4481 mock_delete_floating_ip_by_id.side_effect = ConnectionError(
4482 "Connection failed."
4483 )
4484 volumes_to_hold = []
4485 keep_waiting = True
4486 with self.assertRaises(VimConnConnectionException):
4487 result = self.vimconn._delete_created_items(
4488 created_items, volumes_to_hold, keep_waiting
4489 )
4490 self.assertEqual(result, None)
4491 self.assertEqual(mock_get_item_name_id.call_count, 1)
4492 mock_delete_volumes_by_id_wth_cinder.assert_not_called()
4493 mock_delete_floating_ip_by_id.assert_called_once_with(
4494 f"floating_ip:{floating_network_vim_id}",
4495 f"{floating_network_vim_id}",
4496 created_items,
4497 )
4498 self.vimconn.logger.error.assert_called_once_with(
4499 "Error deleting floating_ip:108b73-e9cc-5a6a-t270-82cc4811bd4a: Connection failed."
4500 )
4502 @patch.object(vimconnector, "_get_item_name_id")
4503 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4504 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4505 def test_delete_created_items_get_item_name_raises_type_error__operation_fails(
4506 self,
4507 mock_delete_floating_ip_by_id,
4508 mock_delete_volumes_by_id_wth_cinder,
4509 mock_get_item_name_id,
4510 ):
4511 """Get item, name raises exception."""
4512 created_items = {
4513 3: True,
4514 f"volume{volume_id}": True,
4515 f"port:{port_id}": None,
4516 }
4517 mock_get_item_name_id.side_effect = [
4518 TypeError("Invalid Type"),
4519 AttributeError("Invalid attribute"),
4520 ]
4521 volumes_to_hold = []
4522 keep_waiting = False
4523 with self.assertRaises(VimConnException):
4524 result = self.vimconn._delete_created_items(
4525 created_items, volumes_to_hold, keep_waiting
4526 )
4527 self.assertEqual(result, None)
4528 self.assertEqual(mock_get_item_name_id.call_count, 1)
4529 mock_delete_volumes_by_id_wth_cinder.assert_not_called()
4530 mock_delete_floating_ip_by_id.assert_not_called()
4531 _call_logger = self.vimconn.logger.error.call_args_list
4532 self.assertEqual(_call_logger[0][0], ("Error deleting 3: Invalid Type",))
4534 @patch.object(vimconnector, "_get_item_name_id")
4535 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4536 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4537 def test_delete_created_items_no_fip_wth_port(
4538 self,
4539 mock_delete_floating_ip_by_id,
4540 mock_delete_volumes_by_id_wth_cinder,
4541 mock_get_item_name_id,
4542 ):
4543 """Created items has port, does not have floating ip."""
4544 created_items = {
4545 f"volume:{volume_id}": True,
4546 f"port:{port_id}": True,
4547 }
4548 mock_get_item_name_id.side_effect = [
4549 ("volume", f"{volume_id}"),
4550 ("port", f"{port_id}"),
4551 ]
4552 mock_delete_volumes_by_id_wth_cinder.return_value = False
4553 volumes_to_hold = []
4554 keep_waiting = False
4555 result = self.vimconn._delete_created_items(
4556 created_items, volumes_to_hold, keep_waiting
4557 )
4558 self.assertEqual(result, False)
4559 self.assertEqual(mock_get_item_name_id.call_count, 2)
4560 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
4561 f"volume:{volume_id}", f"{volume_id}", [], created_items
4562 )
4563 mock_delete_floating_ip_by_id.assert_not_called()
4564 self.vimconn.logger.error.assert_not_called()
4566 @patch.object(vimconnector, "_get_item_name_id")
4567 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4568 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4569 def test_delete_created_items_no_volume(
4570 self,
4571 mock_delete_floating_ip_by_id,
4572 mock_delete_volumes_by_id_wth_cinder,
4573 mock_get_item_name_id,
4574 ):
4575 """Created items does not have volume."""
4576 created_items = {
4577 f"floating_ip:{floating_network_vim_id}": True,
4578 f"port:{port_id}": None,
4579 }
4580 mock_get_item_name_id.side_effect = [
4581 ("floating_ip", f"{floating_network_vim_id}")
4582 ]
4583 volumes_to_hold = []
4584 keep_waiting = False
4585 result = self.vimconn._delete_created_items(
4586 created_items, volumes_to_hold, keep_waiting
4587 )
4588 self.assertEqual(result, False)
4589 self.assertEqual(mock_get_item_name_id.call_count, 1)
4590 mock_delete_volumes_by_id_wth_cinder.assert_not_called()
4591 mock_delete_floating_ip_by_id.assert_called_once_with(
4592 f"floating_ip:{floating_network_vim_id}",
4593 f"{floating_network_vim_id}",
4594 created_items,
4595 )
4596 self.vimconn.logger.error.assert_not_called()
4598 @patch.object(vimconnector, "_get_item_name_id")
4599 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4600 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4601 def test_delete_created_items_already_deleted(
4602 self,
4603 mock_delete_floating_ip_by_id,
4604 mock_delete_volumes_by_id_wth_cinder,
4605 mock_get_item_name_id,
4606 ):
4607 """All created items are alerady deleted."""
4608 created_items = {
4609 f"floating_ip:{floating_network_vim_id}": None,
4610 f"volume:{volume_id}": None,
4611 f"port:{port_id}": None,
4612 }
4613 volumes_to_hold = []
4614 keep_waiting = False
4615 result = self.vimconn._delete_created_items(
4616 created_items, volumes_to_hold, keep_waiting
4617 )
4618 self.assertEqual(result, False)
4619 mock_get_item_name_id.assert_not_called()
4620 mock_delete_volumes_by_id_wth_cinder.assert_not_called()
4621 mock_delete_floating_ip_by_id.assert_not_called()
4622 self.vimconn.logger.error.assert_not_called()
4624 @patch("time.sleep")
4625 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4626 @patch.object(vimconnector, "_format_exception")
4627 @patch.object(vimconnector, "_reload_connection")
4628 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4629 @patch.object(vimconnector, "_delete_created_items")
4630 def test_delete_vminstance_successfully(
4631 self,
4632 mock_delete_created_items,
4633 mock_delete_vm_ports_attached_to_network,
4634 mock_reload_connection,
4635 mock_format_exception,
4636 mock_extract_items_wth_keep_flag_from_created_items,
4637 mock_sleep,
4638 ):
4639 vm_id = f"{virtual_mac_id}"
4640 created_items = deepcopy(created_items_all_true)
4641 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4642 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4643 mock_delete_created_items.return_value = False
4644 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4645 mock_reload_connection.assert_called_once()
4646 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
4647 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
4648 mock_delete_created_items.assert_called_once_with(
4649 created_items, volumes_to_hold, False
4650 )
4651 mock_sleep.assert_not_called()
4652 mock_format_exception.assert_not_called()
4653 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4654 created_items
4655 )
4657 @patch("time.sleep")
4658 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4659 @patch.object(vimconnector, "_format_exception")
4660 @patch.object(vimconnector, "_reload_connection")
4661 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4662 @patch.object(vimconnector, "_delete_created_items")
4663 def test_delete_vminstance_created_items_has_keep_flag(
4664 self,
4665 mock_delete_created_items,
4666 mock_delete_vm_ports_attached_to_network,
4667 mock_reload_connection,
4668 mock_format_exception,
4669 mock_extract_items_wth_keep_flag_from_created_items,
4670 mock_sleep,
4671 ):
4672 """Created_items includes items which has keep flag."""
4673 vm_id = f"{virtual_mac_id}"
4674 initial_created_items = {
4675 f"port{port_id}": True,
4676 f"floating_ip{floating_network_vim_id}": None,
4677 f"volume{volume_id}keep": True,
4678 f"volume{volume_id2}keep": True,
4679 }
4680 created_items = {
4681 f"port{port_id}": True,
4682 f"floating_ip{floating_network_vim_id}": None,
4683 }
4684 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4685 volumes_to_hold = []
4686 mock_delete_created_items.return_value = False
4687 self.vimconn.delete_vminstance(vm_id, initial_created_items, volumes_to_hold)
4688 mock_reload_connection.assert_called_once()
4689 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
4690 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
4691 mock_delete_created_items.assert_called_once_with(
4692 created_items, volumes_to_hold, False
4693 )
4694 mock_sleep.assert_not_called()
4695 mock_format_exception.assert_not_called()
4696 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4697 initial_created_items
4698 )
4700 @patch("time.sleep")
4701 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4702 @patch.object(vimconnector, "_reload_connection")
4703 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4704 @patch.object(vimconnector, "_delete_created_items")
4705 def test_delete_vminstance__extract_items_wth_keep_raises_attributeerror__raise_vimconnexception(
4706 self,
4707 mock_delete_created_items,
4708 mock_delete_vm_ports_attached_to_network,
4709 mock_reload_connection,
4710 mock_extract_items_wth_keep_flag_from_created_items,
4711 mock_sleep,
4712 ):
4713 """extract_items_wth_keep_flag_from_created_items raises AttributeError."""
4714 vm_id = f"{virtual_mac_id}"
4715 initial_created_items = {
4716 f"port{port_id}": True,
4717 f"floating_ip{floating_network_vim_id}": None,
4718 f"volume{volume_id}keep": True,
4719 f"volume{volume_id2}keep": True,
4720 }
4722 mock_extract_items_wth_keep_flag_from_created_items.side_effect = AttributeError
4723 volumes_to_hold = []
4724 mock_delete_created_items.return_value = False
4725 with self.assertRaises(VimConnException):
4726 self.vimconn.delete_vminstance(
4727 vm_id, initial_created_items, volumes_to_hold
4728 )
4729 mock_reload_connection.assert_not_called()
4730 mock_delete_vm_ports_attached_to_network.assert_not_called()
4731 self.vimconn.nova.servers.delete.assert_not_called()
4732 mock_delete_created_items.assert_not_called()
4733 mock_sleep.assert_not_called()
4734 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4735 initial_created_items
4736 )
4738 @patch("time.sleep")
4739 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4740 @patch.object(vimconnector, "_format_exception")
4741 @patch.object(vimconnector, "_reload_connection")
4742 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4743 @patch.object(vimconnector, "_delete_created_items")
4744 def test_delete_vminstance__delete_created_items_returns_true__delete_created_items_called_several_times(
4745 self,
4746 mock_delete_created_items,
4747 mock_delete_vm_ports_attached_to_network,
4748 mock_reload_connection,
4749 mock_format_exception,
4750 mock_extract_items_wth_keep_flag_from_created_items,
4751 mock_sleep,
4752 ):
4753 """Delete creted items raises exception."""
4754 vm_id = f"{virtual_mac_id}"
4755 created_items = deepcopy(created_items_all_true)
4756 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4757 mock_sleep = MagicMock()
4758 volumes_to_hold = []
4759 mock_delete_created_items.side_effect = [True, False]
4760 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4761 mock_reload_connection.assert_called_once()
4762 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
4763 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
4764 self.assertEqual(mock_delete_created_items.call_count, 2)
4765 mock_sleep.assert_not_called()
4766 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4767 created_items
4768 )
4770 @patch("time.sleep")
4771 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4772 @patch.object(vimconnector, "_reload_connection")
4773 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4774 @patch.object(vimconnector, "_delete_created_items")
4775 def test_delete_vminstance__delete_vm_ports_raises_connection_error__raise_vimconnconnectionexception(
4776 self,
4777 mock_delete_created_items,
4778 mock_delete_vm_ports_attached_to_network,
4779 mock_reload_connection,
4780 mock_extract_items_wth_keep_flag_from_created_items,
4781 mock_sleep,
4782 ):
4783 """Delete vm ports raises exception."""
4784 vm_id = f"{virtual_mac_id}"
4785 created_items = deepcopy(created_items_all_true)
4786 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4787 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4788 err = ConnectionError("ClientException occurred.")
4789 mock_delete_vm_ports_attached_to_network.side_effect = err
4790 mock_delete_created_items.return_value = False
4791 with self.assertRaises(VimConnConnectionException):
4792 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4793 mock_reload_connection.assert_called_once()
4794 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
4795 self.vimconn.nova.servers.delete.assert_not_called()
4796 mock_delete_created_items.assert_not_called()
4797 mock_sleep.assert_not_called()
4798 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4799 created_items
4800 )
4802 @patch("time.sleep")
4803 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4804 @patch.object(vimconnector, "_reload_connection")
4805 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4806 @patch.object(vimconnector, "_delete_created_items")
4807 def test_delete_vminstance__nova_server_delete_raises_clientexception__raise_vimconn_unexpected_response(
4808 self,
4809 mock_delete_created_items,
4810 mock_delete_vm_ports_attached_to_network,
4811 mock_reload_connection,
4812 mock_extract_items_wth_keep_flag_from_created_items,
4813 mock_sleep,
4814 ):
4815 """Nova server delete raises exception."""
4816 vm_id = f"{virtual_mac_id}"
4817 created_items = deepcopy(created_items_all_true)
4818 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4819 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4820 err = nvExceptions.ClientException("ClientException occurred.")
4821 self.vimconn.nova.servers.delete.side_effect = err
4822 mock_delete_created_items.side_effect = err
4823 with self.assertRaises(VimConnUnexpectedResponse):
4824 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4825 mock_reload_connection.assert_called_once()
4826 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
4827 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
4828 mock_delete_created_items.assert_not_called()
4829 mock_sleep.assert_not_called()
4830 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4831 created_items
4832 )
4834 @patch("time.sleep")
4835 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4836 @patch.object(vimconnector, "_reload_connection")
4837 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4838 @patch.object(vimconnector, "_delete_created_items")
4839 def test_delete_vminstance__reload_connection_raises_connection_error__raises_vimconnconnection_exception(
4840 self,
4841 mock_delete_created_items,
4842 mock_delete_vm_ports_attached_to_network,
4843 mock_reload_connection,
4844 mock_extract_items_wth_keep_flag_from_created_items,
4845 mock_sleep,
4846 ):
4847 """Reload connection raises exception."""
4848 vm_id = f"{virtual_mac_id}"
4849 created_items = deepcopy(created_items_all_true)
4850 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4851 mock_sleep = MagicMock()
4852 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4853 err = ConnectionError("ClientException occurred.")
4854 mock_delete_created_items.return_value = False
4855 mock_reload_connection.side_effect = err
4856 with self.assertRaises(VimConnConnectionException):
4857 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4858 mock_reload_connection.assert_called_once()
4859 mock_delete_vm_ports_attached_to_network.assert_not_called()
4860 self.vimconn.nova.servers.delete.assert_not_called()
4861 mock_delete_created_items.assert_not_called()
4862 mock_sleep.assert_not_called()
4863 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4864 created_items
4865 )
4867 @patch("time.sleep")
4868 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4869 @patch.object(vimconnector, "_format_exception")
4870 @patch.object(vimconnector, "_reload_connection")
4871 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4872 @patch.object(vimconnector, "_delete_created_items")
4873 def test_delete_vminstance_created_item_vol_to_hold_are_none(
4874 self,
4875 mock_delete_created_items,
4876 mock_delete_vm_ports_attached_to_network,
4877 mock_reload_connection,
4878 mock_format_exception,
4879 mock_extract_items_wth_keep_flag_from_created_items,
4880 mock_sleep,
4881 ):
4882 """created_items and volumes_to_hold are None."""
4883 vm_id = f"{virtual_mac_id}"
4884 created_items = None
4885 volumes_to_hold = None
4886 mock_extract_items_wth_keep_flag_from_created_items.return_value = {}
4887 mock_delete_created_items.return_value = False
4888 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4889 mock_reload_connection.assert_called_once()
4890 mock_delete_vm_ports_attached_to_network.assert_not_called()
4891 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
4892 mock_delete_created_items.assert_called_once_with({}, [], False)
4893 mock_sleep.assert_not_called()
4894 mock_format_exception.assert_not_called()
4895 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with({})
4897 @patch("time.sleep")
4898 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4899 @patch.object(vimconnector, "_format_exception")
4900 @patch.object(vimconnector, "_reload_connection")
4901 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4902 @patch.object(vimconnector, "_delete_created_items")
4903 def test_delete_vminstance_vm_id_is_none(
4904 self,
4905 mock_delete_created_items,
4906 mock_delete_vm_ports_attached_to_network,
4907 mock_reload_connection,
4908 mock_format_exception,
4909 mock_extract_items_wth_keep_flag_from_created_items,
4910 mock_sleep,
4911 ):
4912 """vm_id is None."""
4913 vm_id = None
4914 created_items = deepcopy(created_items_all_true)
4915 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4916 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4917 mock_delete_created_items.side_effect = [True, True, False]
4918 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4919 mock_reload_connection.assert_called_once()
4920 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
4921 self.vimconn.nova.servers.delete.assert_not_called()
4922 self.assertEqual(mock_delete_created_items.call_count, 3)
4923 self.assertEqual(mock_sleep.call_count, 2)
4924 mock_format_exception.assert_not_called()
4925 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4926 created_items
4927 )
4929 @patch("time.sleep")
4930 @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
4931 @patch.object(vimconnector, "_format_exception")
4932 @patch.object(vimconnector, "_reload_connection")
4933 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
4934 @patch.object(vimconnector, "_delete_created_items")
4935 def test_delete_vminstance_delete_created_items_return_true(
4936 self,
4937 mock_delete_created_items,
4938 mock_delete_vm_ports_attached_to_network,
4939 mock_reload_connection,
4940 mock_format_exception,
4941 mock_extract_items_wth_keep_flag_from_created_items,
4942 mock_sleep,
4943 ):
4944 """Delete created items always return True."""
4945 vm_id = None
4946 created_items = deepcopy(created_items_all_true)
4947 mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
4948 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
4949 mock_delete_created_items.side_effect = [True] * 1800
4950 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
4951 mock_reload_connection.assert_called_once()
4952 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
4953 self.vimconn.nova.servers.delete.assert_not_called()
4954 self.assertEqual(mock_delete_created_items.call_count, 1800)
4955 self.assertEqual(mock_sleep.call_count, 1800)
4956 mock_format_exception.assert_not_called()
4957 mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
4958 created_items
4959 )
4961 def test_remove_keep_tag_from_persistent_volumes_keep_flag_exists(self):
4962 """Keep flag exists in created items."""
4963 created_items = {
4964 f"port:{port_id}": True,
4965 f"floating_ip:{floating_network_vim_id}": True,
4966 f"volume:{volume_id}:keep": True,
4967 f"volume:{volume_id2}:keep": True,
4968 }
4969 expected_result = {
4970 f"port:{port_id}": True,
4971 f"floating_ip:{floating_network_vim_id}": True,
4972 f"volume:{volume_id}": True,
4973 f"volume:{volume_id2}": True,
4974 }
4975 result = self.vimconn.remove_keep_tag_from_persistent_volumes(created_items)
4976 self.assertDictEqual(result, expected_result)
4978 def test_remove_keep_tag_from_persistent_volumes_without_keep_flag(self):
4979 """Keep flag does not exist in created items."""
4980 created_items = {
4981 f"port:{port_id}": True,
4982 f"floating_ip:{floating_network_vim_id}": True,
4983 f"volume:{volume_id}": True,
4984 f"volume:{volume_id2}": True,
4985 }
4986 result = self.vimconn.remove_keep_tag_from_persistent_volumes(created_items)
4987 self.assertDictEqual(result, created_items)
4989 def test_update_block_device_mapping_empty_volume(self):
4990 volume = ""
4991 block_device_mapping = {}
4992 base_disk_index = 100
4993 disk = {}
4994 created_items = {}
4995 with self.assertRaises(VimConnException) as err:
4996 self.vimconn.update_block_device_mapping(
4997 volume, block_device_mapping, base_disk_index, disk, created_items
4998 )
4999 self.assertEqual(str(err), "Volume is empty.")
5000 self.assertEqual(block_device_mapping, {})
5001 self.assertEqual(created_items, {})
5003 def test_update_block_device_mapping_invalid_volume(self):
5004 volume = "Volume-A"
5005 block_device_mapping = {}
5006 base_disk_index = 100
5007 disk = {}
5008 created_items = {}
5009 with self.assertRaises(VimConnException) as err:
5010 self.vimconn.update_block_device_mapping(
5011 volume, block_device_mapping, base_disk_index, disk, created_items
5012 )
5013 self.assertEqual(
5014 str(err), "Created volume is not valid, does not have id attribute."
5015 )
5016 self.assertEqual(block_device_mapping, {})
5017 self.assertEqual(created_items, {})
5019 def test_update_block_device_mapping(self):
5020 volume = MagicMock(autospec=True)
5021 volume.id = volume_id
5022 block_device_mapping = {}
5023 base_disk_index = 100
5024 disk = {}
5025 created_items = {}
5026 self.vimconn.update_block_device_mapping(
5027 volume, block_device_mapping, base_disk_index, disk, created_items
5028 )
5029 self.assertEqual(
5030 block_device_mapping, {"vdd": "ac408b73-b9cc-4a6a-a270-82cc4811bd4a"}
5031 )
5032 self.assertEqual(
5033 created_items, {"volume:ac408b73-b9cc-4a6a-a270-82cc4811bd4a": True}
5034 )
5036 def test_update_block_device_mapping_with_keep_flag(self):
5037 volume = MagicMock(autospec=True)
5038 volume.id = volume_id
5039 block_device_mapping = {}
5040 base_disk_index = 100
5041 disk = {"size": 10, "keep": True}
5042 created_items = {}
5043 self.vimconn.update_block_device_mapping(
5044 volume, block_device_mapping, base_disk_index, disk, created_items
5045 )
5046 self.assertEqual(
5047 block_device_mapping, {"vdd": "ac408b73-b9cc-4a6a-a270-82cc4811bd4a"}
5048 )
5049 self.assertEqual(
5050 created_items, {"volume:ac408b73-b9cc-4a6a-a270-82cc4811bd4a:keep": True}
5051 )
5053 def test_extract_items_with_keep_flag_item_has_keep_flag(self):
5054 created_items = deepcopy(created_items_all_true)
5055 created_items[f"volume:{volume_id2}:keep"] = True
5056 result = self.vimconn._extract_items_wth_keep_flag_from_created_items(
5057 created_items
5058 )
5059 self.assertEqual(result, deepcopy(created_items_all_true))
5061 def test_extract_items_with_keep_flag_no_item_wth_keep_flag(self):
5062 created_items = deepcopy(created_items_all_true)
5063 result = self.vimconn._extract_items_wth_keep_flag_from_created_items(
5064 created_items
5065 )
5066 self.assertEqual(result, deepcopy(created_items_all_true))
5068 def test_extract_items_with_keep_flag_all_items_are_already_deleted(self):
5069 created_items = {
5070 f"port:{port_id}": None,
5071 f"floating_ip:{floating_network_vim_id}": None,
5072 f"volume:{volume_id}:keep": None,
5073 f"volume:{volume_id2}:keep": None,
5074 }
5075 expected_result = {
5076 f"port:{port_id}": None,
5077 f"floating_ip:{floating_network_vim_id}": None,
5078 }
5079 result = self.vimconn._extract_items_wth_keep_flag_from_created_items(
5080 created_items
5081 )
5082 self.assertEqual(result, expected_result)
5084 def test_extract_items_with_keep_flag_without_semicolon(self):
5085 created_items = {
5086 f"port{port_id}": True,
5087 f"floating_ip{floating_network_vim_id}": None,
5088 f"volume{volume_id}keep": True,
5089 f"volume{volume_id2}keep": True,
5090 }
5091 result = self.vimconn._extract_items_wth_keep_flag_from_created_items(
5092 created_items
5093 )
5094 self.assertEqual(result, {})
5096 def test_extract_items_with_keep_flag_invalid_type_created_items(self):
5097 created_items = [{f"port{port_id}": True}, {f"volume{volume_id2}keep": True}]
5098 with self.assertRaises(AttributeError):
5099 self.vimconn._extract_items_wth_keep_flag_from_created_items(created_items)
5101 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
5102 def test_get_monitoring_data(self, mock_reload_conection):
5103 flavors = [
5104 {"original_name": "flavor1", "id": "367fc1eb-bd22-40f8-a519-ed2fb4e5976b"},
5105 {"original_name": "flavor2", "id": "5dcf9732-d17d-40b3-910d-37fc4c5aacc0"},
5106 ]
5107 servers = [
5108 Server(
5109 "server1", "ACTIVE", flavors[0], "312200db-42e3-4772-9518-d5db85468392"
5110 ),
5111 Server(
5112 "server2", "ACTIVE", flavors[1], "39a166cf-e4e6-479c-b88c-9ad558cf2cbf"
5113 ),
5114 ]
5115 ports = {"ports": ["port1", "port2"]}
5116 self.vimconn.nova.servers.list.return_value = servers
5117 self.vimconn.neutron.list_ports.return_value = ports
5118 result = self.vimconn.get_monitoring_data()
5119 self.assertTupleEqual(result, (servers, ports))
5120 mock_reload_conection.assert_called_once()
5121 self.vimconn.nova.servers.list.assert_called_once_with(detailed=True)
5122 self.vimconn.neutron.list_ports.assert_called_once()
5124 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
5125 def test_get_monitoring_data_reload_connection_raises(self, mock_reload_conection):
5126 mock_reload_conection.side_effect = VimConnNotFoundException(
5127 "Connection object not found."
5128 )
5129 with self.assertRaises(VimConnException) as err:
5130 result = self.vimconn.get_monitoring_data()
5131 self.assertTupleEqual(result, None)
5132 self.assertEqual(
5133 str(err.exception.args[0]),
5134 "Exception in monitoring while getting VMs and ports status: Connection object not found.",
5135 )
5136 mock_reload_conection.assert_called_once()
5137 check_if_assert_not_called(
5138 [self.vimconn.nova.servers.list, self.vimconn.neutron.list_ports]
5139 )
5141 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
5142 def test_get_monitoring_data_server_list_raises(self, mock_reload_conection):
5143 self.vimconn.nova.servers.list.side_effect = VimConnConnectionException(
5144 "Can not connect to Cloud API."
5145 )
5146 with self.assertRaises(VimConnException) as err:
5147 result = self.vimconn.get_monitoring_data()
5148 self.assertTupleEqual(result, None)
5149 self.assertEqual(
5150 str(err.exception.args[0]),
5151 "Exception in monitoring while getting VMs and ports status: Can not connect to Cloud API.",
5152 )
5153 mock_reload_conection.assert_called_once()
5154 self.vimconn.nova.servers.list.assert_called_once_with(detailed=True)
5155 self.vimconn.neutron.list_ports.assert_not_called()
5157 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
5158 def test_get_monitoring_data_list_ports_raises(self, mock_reload_conection):
5159 self.vimconn.neutron.list_ports.side_effect = VimConnConnectionException(
5160 "Can not connect to Cloud API."
5161 )
5162 with self.assertRaises(VimConnException) as err:
5163 result = self.vimconn.get_monitoring_data()
5164 self.assertTupleEqual(result, None)
5165 self.assertEqual(
5166 str(err.exception.args[0]),
5167 "Exception in monitoring while getting VMs and ports status: Can not connect to Cloud API.",
5168 )
5169 mock_reload_conection.assert_called_once()
5170 self.vimconn.nova.servers.list.assert_called_once_with(detailed=True)
5171 self.vimconn.neutron.list_ports.assert_called_once()
5174class TestNewFlavor(unittest.TestCase):
5175 @patch("logging.getLogger", autospec=True)
5176 def setUp(self, mock_logger):
5177 # We are disabling the logging of exception not to print them to console.
5178 mock_logger = logging.getLogger()
5179 mock_logger.disabled = True
5180 self.vimconn = vimconnector(
5181 "123",
5182 "openstackvim",
5183 "456",
5184 "789",
5185 "http://dummy.url",
5186 None,
5187 "user",
5188 "pass",
5189 )
5190 self.vimconn.nova = CopyingMock(autospec=True)
5191 self.flavor1 = CopyingMock(autospec=True, name="sample-flavor")
5192 self.flavor2 = CopyingMock(autospec=True, name="other-flavor")
5193 self.new_flavor = CopyingMock(autospec=True, name="new_flavor")
5194 self.new_flavor.id = "075d2482-5edb-43e3-91b3-234e65b6268a"
5195 self.vimconn.nova.flavors.create.return_value = self.new_flavor
5197 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5198 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5199 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5200 @patch.object(
5201 vimconnector,
5202 "process_numa_paired_threads",
5203 new_callable=CopyingMock(),
5204 )
5205 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5206 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5207 def test_process_numa_parameters_of_flavor_id_memory_vcpu_in_numa_type_vio(
5208 self,
5209 mock_process_numa_threads,
5210 mock_process_numa_cores,
5211 mock_process_numa_paired_threads,
5212 mock_process_numa_vcpu,
5213 mock_process_numa_memory,
5214 mock_process_vio_numa_nodes,
5215 ):
5216 """Process numa parameters, id, memory, vcpu exist, vim type is VIO,
5217 paired-threads, cores, threads do not exist in numa.
5218 """
5219 numas = [
5220 {"id": 0, "memory": 1, "vcpu": [1, 3]},
5221 {"id": 1, "memory": 2, "vcpu": [2]},
5222 ]
5223 extra_specs = {}
5224 expected_extra_specs = {
5225 "hw:numa_nodes": "2",
5226 "hw:cpu_sockets": "2",
5227 }
5228 self.vimconn.vim_type = "VIO"
5229 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5231 self.assertEqual(mock_process_numa_memory.call_count, 2)
5232 self.assertEqual(mock_process_numa_vcpu.call_count, 2)
5233 mock_process_vio_numa_nodes.assert_called_once_with(2, {"hw:numa_nodes": "2"})
5234 _call_mock_process_numa_memory = mock_process_numa_memory.call_args_list
5235 self.assertEqual(
5236 _call_mock_process_numa_memory[0].args,
5237 (
5238 {"id": 0, "memory": 1, "vcpu": [1, 3]},
5239 0,
5240 {
5241 "hw:numa_nodes": "2",
5242 },
5243 ),
5244 )
5245 self.assertEqual(
5246 _call_mock_process_numa_memory[1].args,
5247 (
5248 {"id": 1, "memory": 2, "vcpu": [2]},
5249 1,
5250 {
5251 "hw:cpu_sockets": "2",
5252 "hw:numa_nodes": "2",
5253 },
5254 ),
5255 )
5256 _call_mock_process_numa_vcpu = mock_process_numa_vcpu.call_args_list
5257 self.assertEqual(
5258 _call_mock_process_numa_vcpu[0].args,
5259 (
5260 {"id": 0, "memory": 1, "vcpu": [1, 3]},
5261 0,
5262 {
5263 "hw:numa_nodes": "2",
5264 },
5265 ),
5266 )
5267 self.assertEqual(
5268 _call_mock_process_numa_vcpu[1].args,
5269 (
5270 {"id": 1, "memory": 2, "vcpu": [2]},
5271 1,
5272 {
5273 "hw:cpu_sockets": "2",
5274 "hw:numa_nodes": "2",
5275 },
5276 ),
5277 )
5278 self.assertDictEqual(extra_specs, expected_extra_specs)
5279 check_if_assert_not_called(
5280 [
5281 mock_process_numa_threads,
5282 mock_process_numa_cores,
5283 mock_process_numa_paired_threads,
5284 ]
5285 )
5287 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5288 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5289 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5290 @patch.object(
5291 vimconnector,
5292 "process_numa_paired_threads",
5293 new_callable=CopyingMock(),
5294 )
5295 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5296 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5297 def test_process_numa_parameters_of_flavor_id_memory_vcpu_in_numa_type_openstack(
5298 self,
5299 mock_process_numa_threads,
5300 mock_process_numa_cores,
5301 mock_process_numa_paired_threads,
5302 mock_process_numa_vcpu,
5303 mock_process_numa_memory,
5304 mock_process_vio_numa_nodes,
5305 ):
5306 """Process numa parameters, id, memory, vcpu exist, vim type is openstack,
5307 paired-threads, cores, threads do not exist in numa.
5308 """
5309 numas = [
5310 {"id": 0, "memory": 1, "vcpu": [1, 3]},
5311 {"id": 1, "memory": 2, "vcpu": [2]},
5312 ]
5313 extra_specs = {}
5314 expected_extra_specs = {
5315 "hw:numa_nodes": "2",
5316 "hw:cpu_sockets": "2",
5317 }
5318 self.vimconn.vim_type = "openstack"
5319 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5321 self.assertEqual(mock_process_numa_memory.call_count, 2)
5322 self.assertEqual(mock_process_numa_vcpu.call_count, 2)
5323 _call_mock_process_numa_memory = mock_process_numa_memory.call_args_list
5324 self.assertEqual(
5325 _call_mock_process_numa_memory[0].args,
5326 (
5327 {"id": 0, "memory": 1, "vcpu": [1, 3]},
5328 0,
5329 {"hw:numa_nodes": "2"},
5330 ),
5331 )
5332 self.assertEqual(
5333 _call_mock_process_numa_memory[1].args,
5334 (
5335 {"id": 1, "memory": 2, "vcpu": [2]},
5336 1,
5337 {"hw:cpu_sockets": "2", "hw:numa_nodes": "2"},
5338 ),
5339 )
5340 _call_mock_process_numa_vcpu = mock_process_numa_vcpu.call_args_list
5341 self.assertEqual(
5342 _call_mock_process_numa_vcpu[0].args,
5343 (
5344 {"id": 0, "memory": 1, "vcpu": [1, 3]},
5345 0,
5346 {"hw:numa_nodes": "2"},
5347 ),
5348 )
5349 self.assertEqual(
5350 _call_mock_process_numa_vcpu[1].args,
5351 (
5352 {"id": 1, "memory": 2, "vcpu": [2]},
5353 1,
5354 {"hw:cpu_sockets": "2", "hw:numa_nodes": "2"},
5355 ),
5356 )
5357 self.assertDictEqual(extra_specs, expected_extra_specs)
5358 check_if_assert_not_called(
5359 [
5360 mock_process_numa_threads,
5361 mock_process_numa_cores,
5362 mock_process_numa_paired_threads,
5363 ]
5364 )
5366 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5367 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5368 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5369 @patch.object(
5370 vimconnector,
5371 "process_numa_paired_threads",
5372 new_callable=CopyingMock(),
5373 )
5374 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5375 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5376 def test_process_numa_parameters_of_flavor_id_paired_threads_in_numa_type_openstack_extra_spec_not_empty(
5377 self,
5378 mock_process_numa_threads,
5379 mock_process_numa_cores,
5380 mock_process_numa_paired_threads,
5381 mock_process_numa_vcpu,
5382 mock_process_numa_memory,
5383 mock_process_vio_numa_nodes,
5384 ):
5385 """Process numa parameters, id, paired-threads exist, vim type is openstack.
5386 vcpus calculation according to paired-threads in numa, there is extra_spec.
5387 ."""
5388 numas = [{"id": 0, "paired-threads": 3}, {"id": 1, "paired-threads": 3}]
5389 extra_specs = {"some-key": "some-value"}
5390 expected_extra_specs = {
5391 "hw:cpu_sockets": "2",
5392 "hw:cpu_threads": "12",
5393 "hw:numa_nodes": "2",
5394 "some-key": "some-value",
5395 }
5396 self.vimconn.vim_type = "openstack"
5397 mock_process_numa_paired_threads.side_effect = [6, 6]
5398 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5400 check_if_assert_not_called([mock_process_numa_threads, mock_process_numa_cores])
5401 self.assertEqual(mock_process_numa_memory.call_count, 2)
5402 self.assertEqual(mock_process_numa_vcpu.call_count, 2)
5403 self.assertEqual(mock_process_numa_paired_threads.call_count, 2)
5404 _call_mock_process_numa_paired_threads = (
5405 mock_process_numa_paired_threads.call_args_list
5406 )
5407 self.assertEqual(
5408 _call_mock_process_numa_paired_threads[0].args,
5409 (
5410 {"id": 0, "paired-threads": 3},
5411 {"hw:cpu_sockets": "2", "hw:numa_nodes": "2", "some-key": "some-value"},
5412 ),
5413 )
5414 self.assertEqual(
5415 _call_mock_process_numa_paired_threads[1].args,
5416 (
5417 {"id": 1, "paired-threads": 3},
5418 {"hw:cpu_sockets": "2", "hw:numa_nodes": "2", "some-key": "some-value"},
5419 ),
5420 )
5421 self.assertDictEqual(extra_specs, expected_extra_specs)
5423 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5424 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5425 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5426 @patch.object(
5427 vimconnector,
5428 "process_numa_paired_threads",
5429 new_callable=CopyingMock(),
5430 )
5431 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5432 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5433 def test_process_numa_parameters_of_flavor_id_paired_threads_in_numa_type_vio_extra_spec_not_empty(
5434 self,
5435 mock_process_numa_threads,
5436 mock_process_numa_cores,
5437 mock_process_numa_paired_threads,
5438 mock_process_numa_vcpu,
5439 mock_process_numa_memory,
5440 mock_process_vio_numa_nodes,
5441 ):
5442 """Process numa parameters, id, paired-threads exist, vim type is VIO.
5443 vcpus calculation according to paired-threads in numa, there is extra_spec.
5444 """
5445 numas = [{"id": 0, "paired-threads": 2}, {"id": 1, "paired-threads": 2}]
5446 extra_specs = {"some-key": "some-value"}
5447 expected_extra_specs = {
5448 "hw:numa_nodes": "2",
5449 "hw:cpu_sockets": "2",
5450 "hw:cpu_threads": "8",
5451 "some-key": "some-value",
5452 }
5453 self.vimconn.vim_type = "VIO"
5454 mock_process_numa_paired_threads.side_effect = [4, 4]
5455 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5456 check_if_assert_not_called([mock_process_numa_threads, mock_process_numa_cores])
5457 self.assertEqual(mock_process_numa_paired_threads.call_count, 2)
5458 self.assertEqual(mock_process_numa_memory.call_count, 2)
5459 self.assertEqual(mock_process_numa_vcpu.call_count, 2)
5460 _call_mock_process_numa_paired_threads = (
5461 mock_process_numa_paired_threads.call_args_list
5462 )
5463 mock_process_vio_numa_nodes.assert_called_once_with(
5464 2, {"some-key": "some-value", "hw:numa_nodes": "2"}
5465 )
5466 self.assertEqual(
5467 _call_mock_process_numa_paired_threads[0].args,
5468 (
5469 {"id": 0, "paired-threads": 2},
5470 {
5471 "hw:cpu_sockets": "2",
5472 "hw:numa_nodes": "2",
5473 "some-key": "some-value",
5474 },
5475 ),
5476 )
5477 self.assertEqual(
5478 _call_mock_process_numa_paired_threads[1].args,
5479 (
5480 {"id": 1, "paired-threads": 2},
5481 {
5482 "hw:cpu_sockets": "2",
5483 "hw:numa_nodes": "2",
5484 "some-key": "some-value",
5485 },
5486 ),
5487 )
5488 self.assertDictEqual(extra_specs, expected_extra_specs)
5490 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5491 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5492 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5493 @patch.object(
5494 vimconnector,
5495 "process_numa_paired_threads",
5496 new_callable=CopyingMock(),
5497 )
5498 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5499 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5500 def test_process_numa_parameters_of_flavor_id_cores_in_numa_type_openstack(
5501 self,
5502 mock_process_numa_threads,
5503 mock_process_numa_cores,
5504 mock_process_numa_paired_threads,
5505 mock_process_numa_vcpu,
5506 mock_process_numa_memory,
5507 mock_process_vio_numa_nodes,
5508 ):
5509 """Process numa parameters, id, cores exist, vim type is openstack.
5510 vcpus calculation according to cores in numa.
5511 """
5512 numas = [{"id": 0, "cores": 1}, {"id": 1, "cores": 2}]
5513 extra_specs = {}
5514 updated_extra_specs = {"hw:numa_nodes": "2", "hw:cpu_sockets": "2"}
5515 expected_extra_specs = {
5516 "hw:numa_nodes": "2",
5517 "hw:cpu_sockets": "2",
5518 "hw:cpu_cores": "3",
5519 }
5520 self.vimconn.vim_type = "openstack"
5521 mock_process_numa_cores.side_effect = [1, 2]
5522 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5524 check_if_assert_not_called(
5525 [mock_process_numa_threads, mock_process_numa_paired_threads]
5526 )
5527 self.assertEqual(mock_process_numa_cores.call_count, 2)
5528 self.assertEqual(mock_process_numa_memory.call_count, 2)
5529 self.assertEqual(mock_process_numa_vcpu.call_count, 2)
5530 _call_mock_process_numa_cores = mock_process_numa_cores.call_args_list
5531 self.assertEqual(
5532 _call_mock_process_numa_cores[0].args,
5533 ({"id": 0, "cores": 1}, updated_extra_specs),
5534 )
5535 self.assertEqual(
5536 _call_mock_process_numa_cores[1].args,
5537 ({"id": 1, "cores": 2}, updated_extra_specs),
5538 )
5539 self.assertDictEqual(extra_specs, expected_extra_specs)
5541 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5542 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5543 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5544 @patch.object(
5545 vimconnector,
5546 "process_numa_paired_threads",
5547 new_callable=CopyingMock(),
5548 )
5549 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5550 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5551 def test_process_numa_parameters_of_flavor_id_cores_in_numa_type_vio(
5552 self,
5553 mock_process_numa_threads,
5554 mock_process_numa_cores,
5555 mock_process_numa_paired_threads,
5556 mock_process_numa_vcpu,
5557 mock_process_numa_memory,
5558 mock_process_vio_numa_nodes,
5559 ):
5560 """Process numa parameters, id, cores exist, vim type is VIO.
5561 vcpus calculation according to cores in numa.
5562 """
5563 numas = [{"id": 0, "cores": 1}, {"id": 1, "cores": 2}]
5564 extra_specs = {}
5565 expected_extra_specs = {
5566 "hw:cpu_cores": "3",
5567 "hw:cpu_sockets": "2",
5568 "hw:numa_nodes": "2",
5569 }
5570 self.vimconn.vim_type = "VIO"
5571 mock_process_numa_cores.side_effect = [1, 2]
5572 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5573 check_if_assert_not_called(
5574 [mock_process_numa_threads, mock_process_numa_paired_threads]
5575 )
5576 self.assertEqual(mock_process_numa_memory.call_count, 2)
5577 self.assertEqual(mock_process_numa_vcpu.call_count, 2)
5578 self.assertEqual(mock_process_numa_cores.call_count, 2)
5579 mock_process_vio_numa_nodes.assert_called_once_with(2, {"hw:numa_nodes": "2"})
5580 _call_mock_process_numa_cores = mock_process_numa_cores.call_args_list
5581 self.assertEqual(
5582 _call_mock_process_numa_cores[0].args,
5583 (
5584 {"id": 0, "cores": 1},
5585 {
5586 "hw:cpu_sockets": "2",
5587 "hw:numa_nodes": "2",
5588 },
5589 ),
5590 )
5591 self.assertEqual(
5592 _call_mock_process_numa_cores[1].args,
5593 (
5594 {"id": 1, "cores": 2},
5595 {
5596 "hw:cpu_sockets": "2",
5597 "hw:numa_nodes": "2",
5598 },
5599 ),
5600 )
5601 self.assertDictEqual(extra_specs, expected_extra_specs)
5603 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5604 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5605 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5606 @patch.object(
5607 vimconnector,
5608 "process_numa_paired_threads",
5609 new_callable=CopyingMock(),
5610 )
5611 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5612 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5613 def test_process_numa_parameters_of_flavor_without_numa_id_with_threads_type_vio(
5614 self,
5615 mock_process_numa_threads,
5616 mock_process_numa_cores,
5617 mock_process_numa_paired_threads,
5618 mock_process_numa_vcpu,
5619 mock_process_numa_memory,
5620 mock_process_vio_numa_nodes,
5621 ):
5622 """Process numa parameters, memory, vcpu, thread exist, vim type is VIO,
5623 vcpus calculation according threads in numa, there are not numa ids.
5624 """
5625 numas = [
5626 {"memory": 1, "vcpu": [1, 3], "threads": 3},
5627 {"memory": 2, "vcpu": [2]},
5628 ]
5629 extra_specs = {}
5630 expected_extra_specs = {
5631 "hw:numa_nodes": "2",
5632 "hw:cpu_sockets": "2",
5633 "hw:cpu_threads": "3",
5634 }
5635 self.vimconn.vim_type = "VIO"
5636 mock_process_numa_threads.return_value = 3
5637 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5638 check_if_assert_not_called(
5639 [
5640 mock_process_numa_memory,
5641 mock_process_numa_vcpu,
5642 mock_process_numa_cores,
5643 mock_process_numa_paired_threads,
5644 ]
5645 )
5646 mock_process_vio_numa_nodes.assert_called_once_with(2, {"hw:numa_nodes": "2"})
5647 self.assertEqual(mock_process_numa_threads.call_count, 1)
5648 _call_mock_process_numa_threads = mock_process_numa_threads.call_args_list
5649 self.assertEqual(
5650 _call_mock_process_numa_threads[0].args,
5651 (
5652 {"memory": 1, "vcpu": [1, 3], "threads": 3},
5653 {
5654 "hw:cpu_sockets": "2",
5655 "hw:numa_nodes": "2",
5656 },
5657 ),
5658 )
5659 self.assertDictEqual(extra_specs, expected_extra_specs)
5661 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5662 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5663 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5664 @patch.object(
5665 vimconnector,
5666 "process_numa_paired_threads",
5667 new_callable=CopyingMock(autospec=True),
5668 )
5669 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5670 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5671 def test_process_numa_parameters_of_flavor_without_numa_id_with_threads_type_openstack(
5672 self,
5673 mock_process_numa_threads,
5674 mock_process_numa_cores,
5675 mock_process_numa_paired_threads,
5676 mock_process_numa_vcpu,
5677 mock_process_numa_memory,
5678 mock_process_vio_numa_nodes,
5679 ):
5680 """Process numa parameters, memory, vcpu, thread exist, vim type is openstack,
5681 vcpus calculation according threads in numa, there are not numa ids.
5682 """
5683 numas = [
5684 {"memory": 1, "vcpu": [1, 3], "threads": 3},
5685 {"memory": 2, "vcpu": [2]},
5686 ]
5687 extra_specs = {}
5688 expected_extra_specs = {
5689 "hw:numa_nodes": "2",
5690 "hw:cpu_sockets": "2",
5691 "hw:cpu_threads": "3",
5692 }
5693 self.vimconn.vim_type = "openstack"
5694 mock_process_numa_threads.return_value = 3
5695 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5697 check_if_assert_not_called(
5698 [
5699 mock_process_numa_memory,
5700 mock_process_numa_vcpu,
5701 mock_process_numa_cores,
5702 mock_process_numa_paired_threads,
5703 mock_process_vio_numa_nodes,
5704 ]
5705 )
5706 self.assertEqual(mock_process_numa_threads.call_count, 1)
5707 _call_mock_process_numa_threads = mock_process_numa_threads.call_args_list
5708 self.assertEqual(
5709 _call_mock_process_numa_threads[0].args,
5710 (
5711 {"memory": 1, "vcpu": [1, 3], "threads": 3},
5712 {"hw:cpu_sockets": "2", "hw:numa_nodes": "2"},
5713 ),
5714 )
5715 self.assertDictEqual(extra_specs, expected_extra_specs)
5717 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5718 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5719 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5720 @patch.object(
5721 vimconnector,
5722 "process_numa_paired_threads",
5723 new_callable=CopyingMock(),
5724 )
5725 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5726 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5727 def test_process_numa_parameters_of_flavor_empty_numas_list_type_vio(
5728 self,
5729 mock_process_numa_threads,
5730 mock_process_numa_cores,
5731 mock_process_numa_paired_threads,
5732 mock_process_numa_vcpu,
5733 mock_process_numa_memory,
5734 mock_process_vio_numa_nodes,
5735 ):
5736 """Numa list is empty, vim type is VIO."""
5737 numas = []
5738 extra_specs = {}
5739 expected_extra_specs = {"hw:numa_nodes": "0"}
5740 self.vimconn.vim_type = "VIO"
5741 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5742 check_if_assert_not_called(
5743 [
5744 mock_process_numa_memory,
5745 mock_process_numa_vcpu,
5746 mock_process_numa_cores,
5747 mock_process_numa_paired_threads,
5748 mock_process_numa_threads,
5749 ]
5750 )
5751 mock_process_vio_numa_nodes.assert_called_once_with(0, {"hw:numa_nodes": "0"})
5752 self.assertDictEqual(extra_specs, expected_extra_specs)
5754 @patch.object(vimconnector, "process_vio_numa_nodes", new_callable=CopyingMock())
5755 @patch.object(vimconnector, "process_numa_memory", new_callable=CopyingMock())
5756 @patch.object(vimconnector, "process_numa_vcpu", new_callable=CopyingMock())
5757 @patch.object(
5758 vimconnector,
5759 "process_numa_paired_threads",
5760 new_callable=CopyingMock(),
5761 )
5762 @patch.object(vimconnector, "process_numa_cores", new_callable=CopyingMock())
5763 @patch.object(vimconnector, "process_numa_threads", new_callable=CopyingMock())
5764 def test_process_numa_parameters_of_flavor_empty_numas_list_type_openstack(
5765 self,
5766 mock_process_numa_threads,
5767 mock_process_numa_cores,
5768 mock_process_numa_paired_threads,
5769 mock_process_numa_vcpu,
5770 mock_process_numa_memory,
5771 mock_process_vio_numa_nodes,
5772 ):
5773 """Numa list is empty, vim type is openstack."""
5774 numas = []
5775 extra_specs = {}
5776 expected_extra_specs = {"hw:numa_nodes": "0"}
5777 self.vimconn.vim_type = "openstack"
5778 mock_process_numa_threads.return_value = None
5779 self.vimconn._process_numa_parameters_of_flavor(numas, extra_specs)
5781 check_if_assert_not_called(
5782 [
5783 mock_process_numa_memory,
5784 mock_process_numa_vcpu,
5785 mock_process_numa_cores,
5786 mock_process_numa_paired_threads,
5787 mock_process_numa_threads,
5788 mock_process_vio_numa_nodes,
5789 ]
5790 )
5791 self.assertDictEqual(extra_specs, expected_extra_specs)
5793 def test_process_numa_memory_empty_extra_spec(self):
5794 numa = {"memory": 2, "vcpu": [2]}
5795 node_id = 2
5796 extra_specs = {}
5797 expected_extra_spec = {"hw:numa_mem.2": 2048}
5798 self.vimconn.process_numa_memory(numa, node_id, extra_specs)
5799 self.assertDictEqual(extra_specs, expected_extra_spec)
5801 def test_process_numa_memory_not_exist(self):
5802 numa = {"vcpu": [2]}
5803 node_id = 2
5804 extra_specs = {"vmware:latency_sensitivity_level": "high"}
5805 self.vimconn.process_numa_memory(numa, node_id, extra_specs)
5806 self.assertDictEqual(extra_specs, {"vmware:latency_sensitivity_level": "high"})
5808 def test_process_numa_memory_node_id_is_none(self):
5809 numa = {"memory": 2, "vcpu": [2]}
5810 node_id = None
5811 extra_specs = {}
5812 expected_extra_spec = {"hw:numa_mem.None": 2048}
5813 self.vimconn.process_numa_memory(numa, node_id, extra_specs)
5814 self.assertDictEqual(extra_specs, expected_extra_spec)
5816 def test_process_numa_vcpu_empty_extra_spec(self):
5817 numa = {"vcpu": [2]}
5818 node_id = 0
5819 extra_specs = {}
5820 expected_extra_spec = {"hw:numa_cpus.0": "2"}
5821 self.vimconn.process_numa_vcpu(numa, node_id, extra_specs)
5822 self.assertDictEqual(extra_specs, expected_extra_spec)
5824 def test_process_numa_vcpu_not_exist(self):
5825 numa = {"memory": 2}
5826 node_id = 0
5827 extra_specs = {"vmware:latency_sensitivity_level": "high"}
5828 expected_extra_spec = {"vmware:latency_sensitivity_level": "high"}
5829 self.vimconn.process_numa_vcpu(numa, node_id, extra_specs)
5830 self.assertDictEqual(extra_specs, expected_extra_spec)
5832 def test_process_numa_vcpu_empty_node_id(self):
5833 numa = {"vcpu": [2]}
5834 node_id = ""
5835 extra_specs = {}
5836 expected_extra_spec = {"hw:numa_cpus.": "2"}
5837 self.vimconn.process_numa_vcpu(numa, node_id, extra_specs)
5838 self.assertDictEqual(extra_specs, expected_extra_spec)
5840 def test_process_numa_vcpu_empty_numa_dict(self):
5841 numa = {}
5842 node_id = 4
5843 extra_specs = {}
5844 self.vimconn.process_numa_vcpu(numa, node_id, extra_specs)
5845 self.assertDictEqual(extra_specs, {})
5847 def test_process_numa_vcpu_str_node_id(self):
5848 numa = {"vcpu": [2]}
5849 node_id = "12"
5850 extra_specs = {}
5851 expected_extra_spec = {"hw:numa_cpus.12": "2"}
5852 self.vimconn.process_numa_vcpu(numa, node_id, extra_specs)
5853 self.assertDictEqual(extra_specs, expected_extra_spec)
5855 def test_process_numa_paired_threads_empty_extra_spec(self):
5856 numa = {"id": 0, "paired-threads": 3}
5857 extra_specs = {}
5858 expected_extra_spec = {
5859 "hw:cpu_thread_policy": "require",
5860 "hw:cpu_policy": "dedicated",
5861 }
5862 result = self.vimconn.process_numa_paired_threads(numa, extra_specs)
5863 self.assertDictEqual(extra_specs, expected_extra_spec)
5864 self.assertEqual(result, 6)
5866 def test_process_numa_paired_threads_empty_numa(self):
5867 numa = {}
5868 extra_specs = {}
5869 result = self.vimconn.process_numa_paired_threads(numa, extra_specs)
5870 self.assertDictEqual(extra_specs, {})
5871 self.assertEqual(result, None)
5873 def test_process_numa_paired_threads_not_exist(self):
5874 numa = {"vcpu": [2]}
5875 extra_specs = {}
5876 result = self.vimconn.process_numa_paired_threads(numa, extra_specs)
5877 self.assertDictEqual(extra_specs, {})
5878 self.assertEqual(result, None)
5880 def test_process_numa_paired_threads_str_thread_num(self):
5881 numa = {"id": 0, "paired-threads": "3"}
5882 extra_specs = {}
5883 expected_extra_spec = {
5884 "hw:cpu_thread_policy": "require",
5885 "hw:cpu_policy": "dedicated",
5886 }
5887 result = self.vimconn.process_numa_paired_threads(numa, extra_specs)
5888 self.assertDictEqual(extra_specs, expected_extra_spec)
5889 self.assertEqual(result, "33")
5891 def test_process_numa_paired_threads_none_thread_num(self):
5892 numa = {"id": 0, "paired-threads": None}
5893 extra_specs = {}
5894 result = self.vimconn.process_numa_paired_threads(numa, extra_specs)
5895 self.assertDictEqual(extra_specs, {})
5896 self.assertEqual(result, None)
5898 def test_process_numa_cores_empty_extra_spec(self):
5899 numa = {"id": 0, "cores": 1}
5900 extra_specs = {}
5901 expected_extra_spec = {
5902 "hw:cpu_policy": "dedicated",
5903 "hw:cpu_thread_policy": "isolate",
5904 }
5905 result = self.vimconn.process_numa_cores(numa, extra_specs)
5906 self.assertDictEqual(extra_specs, expected_extra_spec)
5907 self.assertEqual(result, 1)
5909 def test_process_numa_cores_not_exist(self):
5910 numa = {"id": 0, "paired-threads": 3}
5911 extra_specs = {}
5912 result = self.vimconn.process_numa_cores(numa, extra_specs)
5913 self.assertDictEqual(extra_specs, {})
5914 self.assertEqual(result, None)
5916 def test_process_numa_cores_empty_numa(self):
5917 numa = {}
5918 extra_specs = expected_extra_spec = {"some-key": "some-val"}
5919 result = self.vimconn.process_numa_cores(numa, extra_specs)
5920 self.assertDictEqual(extra_specs, expected_extra_spec)
5921 self.assertEqual(result, None)
5923 def test_process_numa_cores_none_core_num(self):
5924 numa = {"memory": 1, "cores": None}
5925 extra_specs = {}
5926 result = self.vimconn.process_numa_cores(numa, extra_specs)
5927 self.assertDictEqual(extra_specs, {})
5928 self.assertEqual(result, None)
5930 def test_process_numa_cores_string_core_num(self):
5931 numa = {"id": 0, "cores": "1"}
5932 extra_specs = {"some-key": "some-val"}
5933 expected_extra_spec = {
5934 "hw:cpu_policy": "dedicated",
5935 "hw:cpu_thread_policy": "isolate",
5936 "some-key": "some-val",
5937 }
5938 result = self.vimconn.process_numa_cores(numa, extra_specs)
5939 self.assertDictEqual(extra_specs, expected_extra_spec)
5940 self.assertEqual(result, "1")
5942 def test_process_numa_cores_float_core_num(self):
5943 numa = {"memory": 2, "cores": 10.03}
5944 extra_specs = {"some-key": "some-val"}
5945 expected_extra_spec = {
5946 "hw:cpu_policy": "dedicated",
5947 "hw:cpu_thread_policy": "isolate",
5948 "some-key": "some-val",
5949 }
5950 result = self.vimconn.process_numa_cores(numa, extra_specs)
5951 self.assertDictEqual(extra_specs, expected_extra_spec)
5952 self.assertEqual(result, 10.03)
5954 def test_process_numa_threads_empty_extra_spec_int_thread_num(self):
5955 numa = {"memory": 1, "vcpu": [1, 3], "threads": 3}
5956 extra_specs = {}
5957 expected_extra_spec = {
5958 "hw:cpu_policy": "dedicated",
5959 "hw:cpu_thread_policy": "prefer",
5960 }
5961 result = self.vimconn.process_numa_threads(numa, extra_specs)
5962 self.assertDictEqual(extra_specs, expected_extra_spec)
5963 self.assertEqual(result, 3)
5965 def test_process_numa_threads_empty_numa(self):
5966 numa = {}
5967 extra_specs = {"some-key": "some-val"}
5968 expected_extra_spec = {"some-key": "some-val"}
5969 result = self.vimconn.process_numa_threads(numa, extra_specs)
5970 self.assertDictEqual(extra_specs, expected_extra_spec)
5971 self.assertEqual(result, None)
5973 def test_process_numa_threads_not_exist(self):
5974 numa = {"memory": 1}
5975 extra_specs = expected_extra_spec = {"some-key": "some-val"}
5976 result = self.vimconn.process_numa_threads(numa, extra_specs)
5977 self.assertDictEqual(extra_specs, expected_extra_spec)
5978 self.assertEqual(result, None)
5980 def test_process_numa_threads_str_thread_num(self):
5981 numa = {"vcpu": [1, 3], "threads": "3"}
5982 extra_specs = {}
5983 expected_extra_spec = {
5984 "hw:cpu_policy": "dedicated",
5985 "hw:cpu_thread_policy": "prefer",
5986 }
5987 result = self.vimconn.process_numa_threads(numa, extra_specs)
5988 self.assertDictEqual(extra_specs, expected_extra_spec)
5989 self.assertEqual(result, "3")
5991 def test_process_numa_threads_none_thread_num(self):
5992 numa = {"vcpu": [1, 3], "threads": None}
5993 extra_specs = {}
5994 result = self.vimconn.process_numa_threads(numa, extra_specs)
5995 self.assertDictEqual(extra_specs, {})
5996 self.assertEqual(result, None)
5998 def test_process_numa_threads_float_thread_num(self):
5999 numa = {"memory": 1, "vcpu": [1, 3], "threads": 3.3}
6000 extra_specs = {"some-key": "some-val"}
6001 expected_extra_spec = {
6002 "hw:cpu_policy": "dedicated",
6003 "hw:cpu_thread_policy": "prefer",
6004 "some-key": "some-val",
6005 }
6006 result = self.vimconn.process_numa_threads(numa, extra_specs)
6007 self.assertDictEqual(extra_specs, expected_extra_spec)
6008 self.assertEqual(result, 3.3)
6010 def test_change_the_flavor_name_not_existing_name(self):
6011 """Flavor name does not exist in Openstack flavor list."""
6012 self.flavor1.name = "sample-flavor-3"
6013 self.flavor2.name = "other-flavor-4"
6014 self.vimconn.nova.flavors.list.return_value = [self.flavor1, self.flavor2]
6015 name = "other-flavor-3"
6016 name_suffix = 3
6017 flavor_data = {"name": "other-flavor"}
6018 result = self.vimconn._change_flavor_name(name, name_suffix, flavor_data)
6019 self.assertEqual(result, name)
6020 self.vimconn.nova.flavors.list.assert_called_once()
6021 # Checking whether name_suffix changed or not.
6022 self.assertEqual(name_suffix, 3)
6024 def test_change_the_flavor_name_existing_name(self):
6025 """Flavor name exists in Openstack flavor list."""
6026 self.flavor1.name = "other-flavor-6"
6027 self.flavor2.name = "other-flavor-3"
6028 self.vimconn.nova.flavors.list.return_value = [self.flavor1, self.flavor2]
6029 name = "other-flavor-3"
6030 name_suffix = 5
6031 flavor_data = {"name": "other-flavor"}
6032 expected_result = "other-flavor-7"
6033 result = self.vimconn._change_flavor_name(name, name_suffix, flavor_data)
6034 self.assertEqual(result, expected_result)
6035 # Checking whether name_suffix changed or not.
6036 self.assertEqual(name_suffix, 5)
6037 self.vimconn.nova.flavors.list.assert_called_once()
6039 def test_change_the_flavor_name_flavor_data_does_not_have_name(self):
6040 """Flavor data does not have name."""
6041 self.flavor1.name = "other-flavor-6"
6042 self.flavor2.name = "other-flavor-3"
6043 self.vimconn.nova.flavors.list.return_value = [self.flavor1, self.flavor2]
6044 name = "other-flavor-3"
6045 name_suffix = 5
6046 flavor_data = {}
6047 with self.assertRaises(KeyError):
6048 self.vimconn._change_flavor_name(name, name_suffix, flavor_data)
6049 self.vimconn.nova.flavors.list.assert_called_once()
6050 # Checking whether name_suffix changed or not.
6051 self.assertEqual(name_suffix, 5)
6053 def test_change_the_flavor_name_invalid_name_suffix(self):
6054 """Name suffix is invalid."""
6055 self.flavor1.name = "other-flavor-6"
6056 self.flavor2.name = "other-flavor-3"
6057 self.vimconn.nova.flavors.list.return_value = [self.flavor1, self.flavor2]
6058 name = "other-flavor-3"
6059 name_suffix = "a"
6060 flavor_data = {"name": "other-flavor"}
6061 with self.assertRaises(TypeError):
6062 self.vimconn._change_flavor_name(name, name_suffix, flavor_data)
6063 self.vimconn.nova.flavors.list.assert_called_once()
6064 # Checking whether name_suffix changed or not.
6065 self.assertEqual(name_suffix, "a")
6067 def test_change_the_flavor_name_given_name_is_empty(self):
6068 """Given name is empty string."""
6069 self.flavor1.name = "other-flavor-6"
6070 self.flavor2.name = "other-flavor-3"
6071 self.vimconn.nova.flavors.list.return_value = [self.flavor1, self.flavor2]
6072 name = ""
6073 name_suffix = 3
6074 flavor_data = {"name": "other-flavor"}
6075 result = self.vimconn._change_flavor_name(name, name_suffix, flavor_data)
6076 self.assertEqual(result, "")
6077 self.vimconn.nova.flavors.list.assert_called_once()
6078 # Checking whether name_suffix increased or not.
6079 self.assertEqual(name_suffix, 3)
6081 def test_change_the_flavor_name_given_name_is_none(self):
6082 """Given name is None."""
6083 self.flavor1.name = "other-flavor-6"
6084 self.flavor2.name = "other-flavor-3"
6085 self.vimconn.nova.flavors.list.return_value = [self.flavor1, self.flavor2]
6086 name = None
6087 name_suffix = 6
6088 flavor_data = {"name": "other-flavor"}
6089 result = self.vimconn._change_flavor_name(name, name_suffix, flavor_data)
6090 self.assertEqual(result, None)
6091 self.vimconn.nova.flavors.list.assert_called_once()
6092 # Checking whether name_suffix increased or not.
6093 self.assertEqual(name_suffix, 6)
6095 def test_change_the_flavor_name_empty_nova_flavor_list(self):
6096 """Nova flavor list is empty."""
6097 self.vimconn.nova.flavors.list.return_value = []
6098 name = "other-flavor-3"
6099 name_suffix = 5
6100 flavor_data = {"name": "other-flavor"}
6101 result = self.vimconn._change_flavor_name(name, name_suffix, flavor_data)
6102 self.vimconn.nova.flavors.list.assert_called_once()
6103 self.assertEqual(result, name)
6104 # Checking whether name_suffix increased or not.
6105 self.assertEqual(name_suffix, 5)
6107 @patch.object(
6108 vimconnector,
6109 "_process_numa_parameters_of_flavor",
6110 new_callable=CopyingMock(),
6111 )
6112 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6113 def test_process_extended_config_of_flavor_with_numa_cpu_mem_vif_disk_quota(
6114 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6115 ):
6116 """Process extended config, extended has numas, cpu, mem, vif and disk-io quota."""
6117 numas = [
6118 {"memory": 1, "vcpu": [1, 3], "threads": 3},
6119 {"memory": 2, "vcpu": [2]},
6120 ]
6121 extended = {
6122 "numas": numas,
6123 "cpu-quota": {"limit": 3},
6124 "mem-quota": {"limit": 1},
6125 "vif-quota": {"limit": 10},
6126 "disk-io-quota": {"limit": 50},
6127 "mempage-size": "LARGE",
6128 }
6129 extra_specs = {}
6130 expected_extra_specs = {
6131 "hw:mem_page_size": "large",
6132 }
6133 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6135 self.assertEqual(mock_process_resource_quota.call_count, 4)
6136 mock_process_numa_parameters_of_flavor.assert_called_once_with(numas, {})
6137 self.assertEqual(extra_specs, expected_extra_specs)
6139 @patch.object(
6140 vimconnector,
6141 "_process_numa_parameters_of_flavor",
6142 new_callable=CopyingMock(),
6143 )
6144 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6145 def test_process_extended_config_of_flavor_with_numa_wrong_disk_quota(
6146 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6147 ):
6148 """Process extended config, extended has wrong disk quota key."""
6149 numas = [
6150 {"memory": 1, "threads": 3},
6151 {"memory": 2, "vcpu": [2]},
6152 ]
6153 extended = {
6154 "numas": numas,
6155 "disk-quota": {"limit": 50},
6156 "mempage-size": "PREFER_LARGE",
6157 }
6158 extra_specs = {}
6159 expected_extra_specs = {
6160 "hw:mem_page_size": "any",
6161 }
6162 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6163 mock_process_resource_quota.assert_not_called()
6164 mock_process_numa_parameters_of_flavor.assert_called_once_with(numas, {})
6165 self.assertEqual(extra_specs, expected_extra_specs)
6167 @patch.object(
6168 vimconnector,
6169 "_process_numa_parameters_of_flavor",
6170 new_callable=CopyingMock(),
6171 )
6172 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6173 def test_process_extended_config_of_flavor_without_numa_cpu_mem_vif_disk_quota(
6174 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6175 ):
6176 """Process extended config, extended has cpu, mem, vif and disk-io quota but not numas."""
6177 extended = {
6178 "cpu-quota": {"limit": 3},
6179 "mem-quota": {"limit": 1},
6180 "vif-quota": {"limit": 10},
6181 "disk-io-quota": {"limit": 50},
6182 "mempage-size": "SMALL",
6183 }
6184 extra_specs = {}
6185 expected_extra_specs = {
6186 "hw:mem_page_size": "small",
6187 }
6188 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6189 self.assertEqual(mock_process_resource_quota.call_count, 4)
6190 mock_process_numa_parameters_of_flavor.assert_not_called()
6191 self.assertEqual(extra_specs, expected_extra_specs)
6193 @patch.object(
6194 vimconnector,
6195 "_process_numa_parameters_of_flavor",
6196 new_callable=CopyingMock(),
6197 )
6198 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6199 def test_process_extended_config_of_flavor_with_numa_with_cpu_pinning_mem_policy(
6200 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6201 ):
6202 """Process extended config, extended has cpu, mem quota, cpu-pinning and mem-policy."""
6203 numas = [
6204 {"memory": 1},
6205 {"memory": 2, "vcpu": [2]},
6206 ]
6207 extended = {
6208 "numas": numas,
6209 "cpu-quota": {"limit": 3},
6210 "mem-quota": {"limit": 1},
6211 "mempage-size": "LARGE",
6212 "cpu-pinning-policy": "DEDICATED",
6213 "mem-policy": "STRICT",
6214 }
6215 extra_specs = {}
6216 expected_extra_specs = {
6217 "hw:mem_page_size": "large",
6218 "hw:cpu_policy": "dedicated",
6219 "hw:numa_mempolicy": "strict",
6220 }
6221 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6222 self.assertEqual(mock_process_resource_quota.call_count, 2)
6223 mock_process_numa_parameters_of_flavor.assert_called_once_with(numas, {})
6224 self.assertEqual(extra_specs, expected_extra_specs)
6226 @patch.object(
6227 vimconnector,
6228 "_process_numa_parameters_of_flavor",
6229 new_callable=CopyingMock(),
6230 )
6231 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6232 def test_process_extended_config_of_flavor_without_numa_with_cpu_pinning_mem_policy(
6233 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6234 ):
6235 """Process extended config, extended has cpu, mem quota, cpu-pinning and mem-policy but not numas."""
6236 extended = {
6237 "cpu-quota": {"limit": 3},
6238 "mem-quota": {"limit": 1},
6239 "mempage-size": "LARGE",
6240 "cpu-pinning-policy": "DEDICATED",
6241 "mem-policy": "STRICT",
6242 }
6243 extra_specs = {}
6244 expected_extra_specs = {
6245 "hw:mem_page_size": "large",
6246 "hw:cpu_policy": "dedicated",
6247 "hw:numa_mempolicy": "strict",
6248 }
6249 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6250 self.assertEqual(mock_process_resource_quota.call_count, 2)
6251 mock_process_numa_parameters_of_flavor.assert_not_called()
6252 self.assertEqual(extra_specs, expected_extra_specs)
6254 @patch.object(
6255 vimconnector,
6256 "_process_numa_parameters_of_flavor",
6257 new_callable=CopyingMock(),
6258 )
6259 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6260 def test_process_extended_config_of_flavor_without_numa_with_wrong_mempage_size(
6261 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6262 ):
6263 """Process extended config, extended has wrong mempage-size without numas."""
6264 extended = {
6265 "cpu-quota": {"limit": 3},
6266 "mem-quota": {"limit": 1},
6267 "mempage-size": "SIZE_2GB",
6268 "cpu-pinning-policy": "DEDICATED",
6269 "mem-policy": "STRICT",
6270 }
6271 extra_specs = {}
6273 expected_extra_specs = {
6274 "hw:cpu_policy": "dedicated",
6275 "hw:numa_mempolicy": "strict",
6276 }
6277 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6278 self.assertEqual(mock_process_resource_quota.call_count, 2)
6279 mock_process_numa_parameters_of_flavor.assert_not_called()
6280 self.assertEqual(extra_specs, expected_extra_specs)
6282 @patch.object(
6283 vimconnector,
6284 "_process_numa_parameters_of_flavor",
6285 new_callable=CopyingMock(),
6286 )
6287 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6288 def test_process_extended_config_of_flavor_with_numa_with_wrong_mempage_size(
6289 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6290 ):
6291 """Process extended config, extended has wrong mempage-size with numas."""
6292 numas = [
6293 {"memory": 1},
6294 {"memory": 2, "vcpu": [2]},
6295 ]
6296 extended = {
6297 "numas": numas,
6298 "cpu-quota": {"limit": 3},
6299 "mem-quota": {"limit": 1},
6300 "mempage-size": "SIZE_2GB",
6301 "cpu-pinning-policy": "DEDICATED",
6302 "mem-policy": "STRICT",
6303 }
6304 extra_specs = {}
6305 expected_extra_specs = {
6306 "hw:cpu_policy": "dedicated",
6307 "hw:numa_mempolicy": "strict",
6308 }
6309 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6310 self.assertEqual(mock_process_resource_quota.call_count, 2)
6311 mock_process_numa_parameters_of_flavor.assert_called_once_with(numas, {})
6312 self.assertEqual(extra_specs, expected_extra_specs)
6314 @patch.object(
6315 vimconnector,
6316 "_process_numa_parameters_of_flavor",
6317 new_callable=CopyingMock(),
6318 )
6319 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6320 def test_process_extended_config_of_flavor_none_vcpus(
6321 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6322 ):
6323 """Process extended config, extended has cpu, mem quota, cpu-pinning and mem-policy, vcpus is None."""
6324 numas = [
6325 {"memory": 1},
6326 {"memory": 2, "vcpu": [2]},
6327 ]
6328 extended = {
6329 "numas": numas,
6330 "cpu-quota": {"limit": 3},
6331 "mem-quota": {"limit": 1},
6332 "mempage-size": "SIZE_2GB",
6333 "cpu-pinning-policy": "DEDICATED",
6334 "mem-policy": "STRICT",
6335 }
6336 extra_specs = {}
6337 expected_extra_specs = {
6338 "hw:cpu_policy": "dedicated",
6339 "hw:numa_mempolicy": "strict",
6340 }
6341 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6342 self.assertEqual(mock_process_resource_quota.call_count, 2)
6343 mock_process_numa_parameters_of_flavor.assert_called_once_with(numas, {})
6344 self.assertEqual(extra_specs, expected_extra_specs)
6346 @patch.object(
6347 vimconnector,
6348 "_process_numa_parameters_of_flavor",
6349 new_callable=CopyingMock(),
6350 )
6351 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6352 def test_process_extended_config_of_flavor_none_vcpus_without_numas(
6353 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6354 ):
6355 """Process extended config, extended has cpu, mem quota, cpu-pinning and mem-policy, vcpus is None."""
6356 extended = {
6357 "cpu-quota": {"limit": 3},
6358 "mem-quota": {"limit": 1},
6359 "mempage-size": "SIZE_2GB",
6360 "cpu-pinning-policy": "DEDICATED",
6361 "mem-policy": "STRICT",
6362 }
6363 extra_specs = {"some-key": "some-val"}
6364 expected_extra_specs = {
6365 "hw:cpu_policy": "dedicated",
6366 "hw:numa_mempolicy": "strict",
6367 "some-key": "some-val",
6368 }
6369 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6370 self.assertEqual(mock_process_resource_quota.call_count, 2)
6371 mock_process_numa_parameters_of_flavor.assert_not_called()
6372 self.assertEqual(extra_specs, expected_extra_specs)
6374 @patch.object(
6375 vimconnector,
6376 "_process_numa_parameters_of_flavor",
6377 new_callable=CopyingMock(),
6378 )
6379 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6380 def test_process_extended_config_of_flavor_wrong_cpu_pinning_mem_policy_empty_vcpus(
6381 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6382 ):
6383 """Process extended config, extended has wrong cpu-pinning and mem-policy keys."""
6384 numas = [
6385 {"memory": 1},
6386 {"memory": 2, "vcpu": [2]},
6387 ]
6388 extended = {
6389 "numas": numas,
6390 "cpu-quota": {"limit": 3},
6391 "mem-quota": {"limit": 1},
6392 "mempage-size": "SIZE_2GB",
6393 "cpu-pinning-pol": "DEDICATED",
6394 "mem-pol": "STRICT",
6395 }
6396 extra_specs = {}
6397 expected_extra_specs = {}
6398 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6399 self.assertEqual(mock_process_resource_quota.call_count, 2)
6400 mock_process_numa_parameters_of_flavor.assert_called_once_with(
6401 numas, extra_specs
6402 )
6403 self.assertEqual(extra_specs, expected_extra_specs)
6405 @patch.object(
6406 vimconnector,
6407 "_process_numa_parameters_of_flavor",
6408 new_callable=CopyingMock(),
6409 )
6410 @patch.object(vimconnector, "process_resource_quota", new_callable=CopyingMock())
6411 def test_process_extended_config_of_flavor_empty_extended(
6412 self, mock_process_resource_quota, mock_process_numa_parameters_of_flavor
6413 ):
6414 """Process extended config, extended is empty."""
6415 extended = {}
6416 extra_specs = {}
6417 self.vimconn._process_extended_config_of_flavor(extended, extra_specs)
6418 check_if_assert_not_called(
6419 [mock_process_resource_quota, mock_process_numa_parameters_of_flavor]
6420 )
6421 self.assertEqual(extra_specs, {})
6423 def test_get_flavor_details_empty_flavor_data(self):
6424 flavor_data = {}
6425 expected_result = (64, 1, {}, None)
6426 result = self.vimconn._get_flavor_details(flavor_data)
6427 self.assertEqual(result, expected_result)
6429 def test_get_flavor_details_flavor_data_has_ram_vcpus_extended(self):
6430 flavor_data = {
6431 "ram": 32,
6432 "vcpus": 3,
6433 "extended": {
6434 "some-key": "some-val",
6435 },
6436 }
6437 expected_result = (32, 3, {}, {"some-key": "some-val"})
6438 result = self.vimconn._get_flavor_details(flavor_data)
6439 self.assertEqual(result, expected_result)
6441 def test_get_flavor_details_flavor_data_is_none(self):
6442 flavor_data = None
6443 with self.assertRaises(AttributeError):
6444 self.vimconn._get_flavor_details(flavor_data)
6446 def test_get_flavor_details_flavor_data_has_only_extended(self):
6447 flavor_data = {
6448 "extended": {
6449 "some-key": "some-val",
6450 }
6451 }
6452 expected_result = (64, 1, {}, {"some-key": "some-val"})
6453 result = self.vimconn._get_flavor_details(flavor_data)
6454 self.assertEqual(result, expected_result)
6456 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6457 @patch.object(
6458 vimconnector,
6459 "_process_extended_config_of_flavor",
6460 new_callable=CopyingMock(),
6461 )
6462 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6463 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6464 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6465 def test_new_flavor_with_extended_with_extra_specs(
6466 self,
6467 mock_format_exception,
6468 mock_reload_connection,
6469 mock_change_flavor_name,
6470 mock_extended_config_of_flavor,
6471 mock_get_flavor_details,
6472 ):
6473 """Create new flavor with using extended parameters and extra specs."""
6474 name_suffix = 0
6475 vcpus = 8
6476 mock_change_flavor_name.return_value = name1
6477 mock_get_flavor_details.return_value = (
6478 3,
6479 vcpus,
6480 {"some-key": "some-value"},
6481 extended,
6482 )
6483 expected_result = self.new_flavor.id
6484 result = self.vimconn.new_flavor(flavor_data)
6485 self.assertEqual(result, expected_result)
6486 mock_reload_connection.assert_called_once()
6487 self.new_flavor.set_keys.assert_called_once()
6488 mock_get_flavor_details.assert_called_once_with(flavor_data)
6489 mock_change_flavor_name.assert_called_once_with(name1, name_suffix, flavor_data)
6490 mock_extended_config_of_flavor.assert_called_once_with(
6491 extended, {"some-key": "some-value"}
6492 )
6493 self.vimconn.nova.flavors.create.assert_called_once_with(
6494 name=name1, ram=3, vcpus=8, disk=50, ephemeral=0, swap=0, is_public=True
6495 )
6496 mock_format_exception.assert_not_called()
6498 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6499 @patch.object(
6500 vimconnector,
6501 "_process_extended_config_of_flavor",
6502 new_callable=CopyingMock(),
6503 )
6504 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6505 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6506 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6507 def test_new_flavor_with_extended_without_extra_specs(
6508 self,
6509 mock_format_exception,
6510 mock_reload_connection,
6511 mock_change_flavor_name,
6512 mock_extended_config_of_flavor,
6513 mock_get_flavor_details,
6514 ):
6515 """Create new flavor with using extended parameters without extra specs."""
6516 name_suffix = 0
6517 vcpus = 8
6518 mock_change_flavor_name.return_value = name1
6519 mock_get_flavor_details.return_value = (3, vcpus, {}, extended)
6520 expected_result = self.new_flavor.id
6521 result = self.vimconn.new_flavor(flavor_data)
6522 self.assertEqual(result, expected_result)
6523 mock_reload_connection.assert_called_once()
6524 mock_get_flavor_details.assert_called_once_with(flavor_data)
6525 mock_change_flavor_name.assert_called_once_with(name1, name_suffix, flavor_data)
6526 mock_extended_config_of_flavor.assert_called_once_with(extended, {})
6527 self.vimconn.nova.flavors.create.assert_called_once_with(
6528 name=name1, ram=3, vcpus=vcpus, disk=50, ephemeral=0, swap=0, is_public=True
6529 )
6530 check_if_assert_not_called([self.new_flavor.set_keys, mock_format_exception])
6532 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6533 @patch.object(
6534 vimconnector,
6535 "_process_extended_config_of_flavor",
6536 new_callable=CopyingMock(),
6537 )
6538 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6539 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6540 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6541 def test_new_flavor_change_name_if_used_false_with_extended(
6542 self,
6543 mock_format_exception,
6544 mock_reload_connection,
6545 mock_change_flavor_name,
6546 mock_extended_config_of_flavor,
6547 mock_get_flavor_details,
6548 ):
6549 """Create new flavor, change_name_if_used_false, there is extended."""
6550 vcpus = 8
6551 mock_get_flavor_details.return_value = (3, vcpus, {}, extended)
6552 expected_result = self.new_flavor.id
6553 result = self.vimconn.new_flavor(flavor_data, False)
6554 self.assertEqual(result, expected_result)
6555 mock_reload_connection.assert_called_once()
6556 self.assertEqual(mock_get_flavor_details.call_count, 1)
6557 mock_extended_config_of_flavor.assert_called_once_with(extended, {})
6558 self.vimconn.nova.flavors.create.assert_called_once_with(
6559 name=name1, ram=3, vcpus=8, disk=50, ephemeral=0, swap=0, is_public=True
6560 )
6561 check_if_assert_not_called(
6562 [mock_change_flavor_name, mock_format_exception, self.new_flavor.set_keys]
6563 )
6565 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6566 @patch.object(
6567 vimconnector,
6568 "_process_extended_config_of_flavor",
6569 new_callable=CopyingMock(),
6570 )
6571 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6572 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6573 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6574 def test_new_flavor_change_name_if_used_true_without_extended(
6575 self,
6576 mock_format_exception,
6577 mock_reload_connection,
6578 mock_change_flavor_name,
6579 mock_extended_config_of_flavor,
6580 mock_get_flavor_details,
6581 ):
6582 """Create new flavor without extended parameters."""
6583 name_suffix = 0
6584 mock_change_flavor_name.return_value = name1
6585 expected_result = self.new_flavor.id
6586 mock_get_flavor_details.return_value = (3, 8, {}, None)
6587 result = self.vimconn.new_flavor(flavor_data2)
6588 self.assertEqual(result, expected_result)
6589 mock_reload_connection.assert_called_once()
6590 mock_change_flavor_name.assert_called_once_with(
6591 name1, name_suffix, flavor_data2
6592 )
6593 self.assertEqual(mock_get_flavor_details.call_count, 1)
6594 self.vimconn.nova.flavors.create.assert_called_once_with(
6595 name=name1, ram=3, vcpus=8, disk=50, ephemeral=0, swap=0, is_public=True
6596 )
6597 check_if_assert_not_called(
6598 [
6599 self.new_flavor.set_keys,
6600 mock_extended_config_of_flavor,
6601 mock_format_exception,
6602 ]
6603 )
6605 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6606 @patch.object(
6607 vimconnector,
6608 "_process_extended_config_of_flavor",
6609 new_callable=CopyingMock(),
6610 )
6611 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6612 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6613 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6614 def test_new_flavor_reload_connection_exception(
6615 self,
6616 mock_format_exception,
6617 mock_reload_connection,
6618 mock_change_flavor_name,
6619 mock_extended_config_of_flavor,
6620 mock_get_flavor_details,
6621 ):
6622 """Create new flavor, reload connection exception occurred."""
6623 error_msg = "Can not connect to client APIs."
6624 error = nvExceptions.ClientException(error_msg)
6625 mock_change_flavor_name.return_value = name1
6626 mock_reload_connection.side_effect = error
6627 with self.assertRaises(Exception) as err:
6628 self.vimconn.new_flavor(flavor_data2)
6629 self.assertEqual(str(err.exception), "Can not connect to client APIs.")
6630 self.assertEqual(mock_reload_connection.call_count, 1)
6631 call_mock_format_exception = mock_format_exception.call_args
6632 self.assertEqual(
6633 str(call_mock_format_exception[0][0]), str(ClientException(error_msg))
6634 )
6635 check_if_assert_not_called(
6636 [
6637 mock_change_flavor_name,
6638 mock_get_flavor_details,
6639 mock_extended_config_of_flavor,
6640 self.vimconn.nova.flavors.create,
6641 ]
6642 )
6644 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6645 @patch.object(
6646 vimconnector,
6647 "_process_extended_config_of_flavor",
6648 new_callable=CopyingMock(autospec=True),
6649 )
6650 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6651 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6652 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6653 def test_new_flavor_flavor_data_without_name(
6654 self,
6655 mock_format_exception,
6656 mock_reload_connection,
6657 mock_change_flavor_name,
6658 mock_extended_config_of_flavor,
6659 mock_get_flavor_details,
6660 ):
6661 """Create new flavor, flavor data does not have name."""
6662 flavor_data3 = {
6663 "ram": 3,
6664 "vcpus": 8,
6665 "disk": 50,
6666 }
6667 error_msg = "name"
6668 self.vimconn.new_flavor(flavor_data3)
6669 mock_format_exception.assert_called_once()
6670 call_mock_format_exception = mock_format_exception.call_args
6671 self.assertEqual(
6672 str(call_mock_format_exception[0][0]), str(KeyError(error_msg))
6673 )
6674 check_if_assert_not_called(
6675 [
6676 mock_reload_connection,
6677 mock_change_flavor_name,
6678 mock_get_flavor_details,
6679 mock_extended_config_of_flavor,
6680 self.vimconn.nova.flavors.create,
6681 ]
6682 )
6684 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6685 @patch.object(
6686 vimconnector,
6687 "_process_extended_config_of_flavor",
6688 new_callable=CopyingMock(),
6689 )
6690 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6691 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6692 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6693 def test_new_flavor_change_flavor_name_has_extended_conflict_exception_recovered_in_retry(
6694 self,
6695 mock_format_exception,
6696 mock_reload_connection,
6697 mock_change_flavor_name,
6698 mock_extended_config_of_flavor,
6699 mock_get_flavor_details,
6700 ):
6701 """Create new flavor, nvExceptions.Conflict occurred and recovered, there is extended config."""
6702 name_suffix = 0
6703 error_msg = "Conflict has occurred while creating flavor name."
6704 error2 = nvExceptions.Conflict(error_msg)
6705 mock_change_flavor_name.side_effect = [error2, "sample-flavor-3"]
6706 expected_result = self.new_flavor.id
6707 mock_get_flavor_details.return_value = (3, 8, {}, extended)
6708 result = self.vimconn.new_flavor(flavor_data2)
6709 self.assertEqual(result, expected_result)
6710 self.assertEqual(mock_reload_connection.call_count, 2)
6711 mock_change_flavor_name.assert_called_with(name1, name_suffix, flavor_data2)
6712 self.assertEqual(mock_change_flavor_name.call_count, 2)
6713 self.assertEqual(mock_get_flavor_details.call_count, 1)
6714 self.assertEqual(mock_extended_config_of_flavor.call_count, 1)
6715 self.vimconn.nova.flavors.create.assert_called_once_with(
6716 name="sample-flavor-3",
6717 ram=3,
6718 vcpus=8,
6719 disk=50,
6720 ephemeral=0,
6721 swap=0,
6722 is_public=True,
6723 )
6724 check_if_assert_not_called([self.new_flavor.set_keys, mock_format_exception])
6726 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6727 @patch.object(
6728 vimconnector,
6729 "_process_extended_config_of_flavor",
6730 new_callable=CopyingMock(),
6731 )
6732 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6733 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6734 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6735 def test_new_flavor_change_flavor_name_without_extended_conflict_exception_recovered_in_retry(
6736 self,
6737 mock_format_exception,
6738 mock_reload_connection,
6739 mock_change_flavor_name,
6740 mock_extended_config_of_flavor,
6741 mock_get_flavor_details,
6742 ):
6743 """Create new flavor, nvExceptions.Conflict occurred and recovered, there is not extended config."""
6744 name_suffix = 0
6745 error2 = nvExceptions.Conflict(
6746 "Conflict has occurred while creating flavor name."
6747 )
6748 mock_change_flavor_name.side_effect = [error2, "sample-flavor-3"]
6749 expected_result = self.new_flavor.id
6750 mock_get_flavor_details.return_value = (3, 8, {}, None)
6751 result = self.vimconn.new_flavor(flavor_data2)
6752 self.assertEqual(result, expected_result)
6753 self.assertEqual(mock_reload_connection.call_count, 2)
6754 mock_change_flavor_name.assert_called_with(name1, name_suffix, flavor_data2)
6755 self.assertEqual(mock_change_flavor_name.call_count, 2)
6756 self.assertEqual(mock_get_flavor_details.call_count, 1)
6757 self.vimconn.nova.flavors.create.assert_called_once_with(
6758 name="sample-flavor-3",
6759 ram=3,
6760 vcpus=8,
6761 disk=50,
6762 ephemeral=0,
6763 swap=0,
6764 is_public=True,
6765 )
6766 check_if_assert_not_called(
6767 [
6768 self.new_flavor.set_keys,
6769 mock_extended_config_of_flavor,
6770 mock_format_exception,
6771 ]
6772 )
6774 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6775 @patch.object(
6776 vimconnector,
6777 "_process_extended_config_of_flavor",
6778 new_callable=CopyingMock(),
6779 )
6780 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6781 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6782 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6783 def test_new_flavor_change_flavor_name_conflict_exception_change_name_if_used_false(
6784 self,
6785 mock_format_exception,
6786 mock_reload_connection,
6787 mock_change_flavor_name,
6788 mock_extended_config_of_flavor,
6789 mock_get_flavor_details,
6790 ):
6791 """Create new flavor, nvExceptions.Conflict occurred,
6792 change_name_if_used is false."""
6793 change_name_if_used = False
6794 error_msg = "Conflict has occurred while creating flavor name."
6795 error2 = nvExceptions.Conflict(error_msg)
6796 mock_get_flavor_details.return_value = (4, 8, {}, None)
6797 self.vimconn.nova.flavors.create.side_effect = error2
6798 with self.assertRaises(Exception) as err:
6799 self.vimconn.new_flavor(flavor_data2, change_name_if_used)
6800 self.assertEqual(str(err.exception), error_msg)
6801 self.assertEqual(type(err.exception), nvExceptions.Conflict)
6802 self.vimconn.nova.flavors.create.assert_called_with(
6803 name="sample-flavor",
6804 ram=4,
6805 vcpus=8,
6806 disk=50,
6807 ephemeral=0,
6808 swap=0,
6809 is_public=True,
6810 )
6811 self.assertEqual(mock_get_flavor_details.call_count, 3)
6812 self.assertEqual(self.vimconn.nova.flavors.create.call_count, 3)
6813 self.assertEqual(mock_reload_connection.call_count, 3)
6814 check_if_assert_not_called(
6815 [mock_change_flavor_name, mock_extended_config_of_flavor]
6816 )
6817 _call_mock_format_exception = mock_format_exception.call_args
6818 self.assertEqual(
6819 str(_call_mock_format_exception[0][0]), str(Conflict(error_msg))
6820 )
6821 self.assertEqual(mock_format_exception.call_count, 3)
6823 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6824 @patch.object(
6825 vimconnector,
6826 "_process_extended_config_of_flavor",
6827 new_callable=CopyingMock(),
6828 )
6829 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6830 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6831 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6832 def test_new_flavor_client_exception_occurred_change_name_if_used_true(
6833 self,
6834 mock_format_exception,
6835 mock_reload_connection,
6836 mock_change_flavor_name,
6837 mock_extended_config_of_flavor,
6838 mock_get_flavor_details,
6839 ):
6840 """Create new flavor, nvExceptions.ClientException occurred,
6841 change_name_if_used is true."""
6842 error_msg = "Connection failed."
6843 error2 = nvExceptions.ClientException(error_msg)
6844 mock_change_flavor_name.side_effect = [
6845 "sample-flavor-3",
6846 "sample-flavor-4",
6847 "sample-flavor-5",
6848 ]
6849 mock_get_flavor_details.return_value = (3, 8, {}, None)
6850 self.vimconn.nova.flavors.create.side_effect = error2
6851 with self.assertRaises(Exception) as err:
6852 self.vimconn.new_flavor(flavor_data2)
6853 self.assertEqual(
6854 str(err.exception), "Conflict has occurred while creating flavor name."
6855 )
6856 self.assertEqual(type(err.exception), nvExceptions.Conflict)
6857 self.assertEqual(self.vimconn.nova.flavors.create.call_count, 1)
6858 _call_mock_nova_create_flavor = self.vimconn.nova.flavors.create.call_args_list
6859 self.assertEqual(
6860 _call_mock_nova_create_flavor[0][1],
6861 (
6862 {
6863 "name": "sample-flavor-3",
6864 "ram": 3,
6865 "vcpus": 8,
6866 "disk": 50,
6867 "ephemeral": 0,
6868 "swap": 0,
6869 "is_public": True,
6870 }
6871 ),
6872 )
6874 self.assertEqual(mock_reload_connection.call_count, 1)
6875 self.assertEqual(mock_get_flavor_details.call_count, 1)
6876 _call_mock_change_flavor = mock_change_flavor_name.call_args_list
6877 self.assertEqual(
6878 _call_mock_change_flavor[0][0],
6879 (
6880 "sample-flavor",
6881 0,
6882 {"name": "sample-flavor", "ram": 3, "vcpus": 8, "disk": 50},
6883 ),
6884 )
6885 self.assertEqual(mock_change_flavor_name.call_count, 1)
6886 mock_extended_config_of_flavor.assert_not_called()
6887 call_mock_format_exception = mock_format_exception.call_args
6888 self.assertEqual(
6889 str(call_mock_format_exception[0][0]), str(ClientException(error_msg))
6890 )
6891 self.assertEqual(mock_format_exception.call_count, 1)
6893 @patch.object(vimconnector, "_get_flavor_details", new_callable=CopyingMock())
6894 @patch.object(
6895 vimconnector,
6896 "_process_extended_config_of_flavor",
6897 new_callable=CopyingMock(),
6898 )
6899 @patch.object(vimconnector, "_change_flavor_name", new_callable=CopyingMock())
6900 @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
6901 @patch.object(vimconnector, "_format_exception", new_callable=CopyingMock())
6902 def test_new_flavor_change_flavor_name_conflict_exception_occurred_change_name_if_used_true(
6903 self,
6904 mock_format_exception,
6905 mock_reload_connection,
6906 mock_change_flavor_name,
6907 mock_extended_config_of_flavor,
6908 mock_get_flavor_details,
6909 ):
6910 """Create new flavor, nvExceptions.Conflict occurred,
6911 change_name_if_used is true."""
6912 error_msg = "Conflict has occurred while creating flavor name."
6913 error2 = nvExceptions.Conflict(error_msg)
6914 mock_change_flavor_name.side_effect = [
6915 "sample-flavor-3",
6916 "sample-flavor-4",
6917 "sample-flavor-5",
6918 ]
6919 mock_get_flavor_details.return_value = (3, 8, {}, None)
6920 self.vimconn.nova.flavors.create.side_effect = error2
6921 with self.assertRaises(Exception) as err:
6922 self.vimconn.new_flavor(flavor_data2)
6923 self.assertEqual(str(err.exception), error_msg)
6924 self.assertEqual(type(err.exception), nvExceptions.Conflict)
6925 self.assertEqual(self.vimconn.nova.flavors.create.call_count, 3)
6926 _call_mock_nova_create_flavor = self.vimconn.nova.flavors.create.call_args_list
6927 self.assertEqual(
6928 _call_mock_nova_create_flavor[0][1],
6929 (
6930 {
6931 "name": "sample-flavor-3",
6932 "ram": 3,
6933 "vcpus": 8,
6934 "disk": 50,
6935 "ephemeral": 0,
6936 "swap": 0,
6937 "is_public": True,
6938 }
6939 ),
6940 )
6941 self.assertEqual(
6942 _call_mock_nova_create_flavor[1][1],
6943 (
6944 {
6945 "name": "sample-flavor-4",
6946 "ram": 3,
6947 "vcpus": 8,
6948 "disk": 50,
6949 "ephemeral": 0,
6950 "swap": 0,
6951 "is_public": True,
6952 }
6953 ),
6954 )
6955 self.assertEqual(
6956 _call_mock_nova_create_flavor[2][1],
6957 (
6958 {
6959 "name": "sample-flavor-5",
6960 "ram": 3,
6961 "vcpus": 8,
6962 "disk": 50,
6963 "ephemeral": 0,
6964 "swap": 0,
6965 "is_public": True,
6966 }
6967 ),
6968 )
6969 self.assertEqual(mock_reload_connection.call_count, 3)
6970 _call_mock_change_flavor = mock_change_flavor_name.call_args_list
6971 self.assertEqual(
6972 _call_mock_change_flavor[0][0],
6973 (
6974 "sample-flavor",
6975 0,
6976 {"name": "sample-flavor", "ram": 3, "vcpus": 8, "disk": 50},
6977 ),
6978 )
6979 self.assertEqual(
6980 _call_mock_change_flavor[1][0],
6981 (
6982 "sample-flavor-3",
6983 0,
6984 {"name": "sample-flavor", "ram": 3, "vcpus": 8, "disk": 50},
6985 ),
6986 )
6987 self.assertEqual(
6988 _call_mock_change_flavor[2][0],
6989 (
6990 "sample-flavor-4",
6991 0,
6992 {"name": "sample-flavor", "ram": 3, "vcpus": 8, "disk": 50},
6993 ),
6994 )
6995 self.assertEqual(mock_change_flavor_name.call_count, 3)
6996 mock_extended_config_of_flavor.assert_not_called()
6997 call_mock_format_exception = mock_format_exception.call_args
6998 self.assertEqual(
6999 str(call_mock_format_exception[0][0]), str(Conflict(error_msg))
7000 )
7001 self.assertEqual(mock_format_exception.call_count, 1)
7003 def test_process_process_vio_numa_nodes_without_numa_with_extra_spec(self):
7004 numa_nodes = 0
7005 extra_specs = {"hw:numa_nodes": "0"}
7006 expected_extra_spec = {
7007 "vmware:latency_sensitivity_level": "high",
7008 "hw:numa_nodes": "0",
7009 }
7010 self.vimconn.process_vio_numa_nodes(numa_nodes, extra_specs)
7011 self.assertDictEqual(extra_specs, expected_extra_spec)
7013 def test_process_process_vio_numa_nodes_list_type_numa_nodes_empty_extra_spec(self):
7014 numa_nodes = [7, 9, 4]
7015 extra_specs = {}
7016 expected_extra_spec = {
7017 "vmware:latency_sensitivity_level": "high",
7018 }
7019 self.vimconn.process_vio_numa_nodes(numa_nodes, extra_specs)
7020 self.assertDictEqual(extra_specs, expected_extra_spec)
7022 def test_process_process_vio_numa_nodes_with_numa_with_extra_spec(self):
7023 numa_nodes = 5
7024 extra_specs = {"hw:numa_nodes": "5"}
7025 expected_extra_spec = {
7026 "vmware:latency_sensitivity_level": "high",
7027 "hw:numa_nodes": "5",
7028 }
7029 self.vimconn.process_vio_numa_nodes(numa_nodes, extra_specs)
7030 self.assertDictEqual(extra_specs, expected_extra_spec)
7032 def test_process_process_vio_numa_nodes_none_numa_nodes(self):
7033 numa_nodes = None
7034 extra_specs = {"hw:numa_nodes": "None"}
7035 expected_extra_spec = {
7036 "vmware:latency_sensitivity_level": "high",
7037 "hw:numa_nodes": "None",
7038 }
7039 self.vimconn.process_vio_numa_nodes(numa_nodes, extra_specs)
7040 self.assertDictEqual(extra_specs, expected_extra_spec)
7042 def test_process_process_vio_numa_nodes_invalid_type_extra_specs(self):
7043 numa_nodes = 5
7044 extra_specs = []
7045 with self.assertRaises(TypeError):
7046 self.vimconn.process_vio_numa_nodes(numa_nodes, extra_specs)
7049if __name__ == "__main__":
7050 unittest.main()