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