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