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