Code Coverage

Cobertura Coverage Report > RO-VIM-openstack.osm_rovim_openstack.tests >

test_vimconn_openstack.py

Trend

File Coverage summary

NameClassesLinesConditionals
test_vimconn_openstack.py
100%
1/1
99%
3122/3146
100%
0/0

Coverage Breakdown by Class

NameLinesConditionals
test_vimconn_openstack.py
99%
3122/3146
N/A

Source

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