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