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