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