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