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