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