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