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