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