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