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