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