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