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