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