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