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