bdd6bed92814df29c38992dbfed2caa9ed6ab470
[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 def test_prepare_persistent_non_root_volumes_vim_using_volume_id(self):
2246 """Existing persistent non root volume with vim_volume_id."""
2247 vm_av_zone = ["nova"]
2248 base_disk_index = ord("b")
2249 disk = {"vim_volume_id": volume_id}
2250 block_device_mapping = {}
2251 existing_vim_volumes = []
2252 created_items = {}
2253 expected_block_device_mapping = {"vdb": volume_id}
2254 expected_existing_vim_volumes = [{"id": volume_id}]
2255 self.vimconn._prepare_non_root_persistent_volumes(
2256 name,
2257 disk,
2258 vm_av_zone,
2259 block_device_mapping,
2260 base_disk_index,
2261 existing_vim_volumes,
2262 created_items,
2263 )
2264 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2265 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2266 self.vimconn.cinder.volumes.create.assert_not_called()
2267
2268 def test_prepare_persistent_root_volumes_using_vim_id(self):
2269 """Existing persistent root volume with vim_id."""
2270 vm_av_zone = ["nova"]
2271 base_disk_index = ord("a")
2272 disk = {"vim_id": volume_id}
2273 block_device_mapping = {}
2274 existing_vim_volumes = []
2275 created_items = {}
2276 expected_boot_vol_id = None
2277 expected_block_device_mapping = {"vda": volume_id}
2278 expected_existing_vim_volumes = [{"id": volume_id}]
2279 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
2280 name,
2281 vm_av_zone,
2282 disk,
2283 base_disk_index,
2284 block_device_mapping,
2285 existing_vim_volumes,
2286 created_items,
2287 )
2288 self.assertEqual(boot_volume_id, expected_boot_vol_id)
2289 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2290 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2291 self.vimconn.cinder.volumes.create.assert_not_called()
2292
2293 def test_prepare_persistent_non_root_volumes_using_vim_id(self):
2294 """Existing persistent root volume with vim_id."""
2295 vm_av_zone = ["nova"]
2296 base_disk_index = ord("b")
2297 disk = {"vim_id": volume_id}
2298 block_device_mapping = {}
2299 existing_vim_volumes = []
2300 created_items = {}
2301
2302 expected_block_device_mapping = {"vdb": volume_id}
2303 expected_existing_vim_volumes = [{"id": volume_id}]
2304 self.vimconn._prepare_non_root_persistent_volumes(
2305 name,
2306 disk,
2307 vm_av_zone,
2308 block_device_mapping,
2309 base_disk_index,
2310 existing_vim_volumes,
2311 created_items,
2312 )
2313
2314 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2315 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2316 self.vimconn.cinder.volumes.create.assert_not_called()
2317
2318 def test_prepare_persistent_root_volumes_create(self):
2319 """Create persistent root volume."""
2320 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
2321 vm_av_zone = ["nova"]
2322 base_disk_index = ord("a")
2323 disk = {"size": 10, "image_id": image_id}
2324 block_device_mapping = {}
2325 existing_vim_volumes = []
2326 created_items = {}
2327 expected_boot_vol_id = volume_id2
2328 expected_block_device_mapping = {"vda": volume_id2}
2329 expected_existing_vim_volumes = []
2330 boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
2331 name,
2332 vm_av_zone,
2333 disk,
2334 base_disk_index,
2335 block_device_mapping,
2336 existing_vim_volumes,
2337 created_items,
2338 )
2339 self.assertEqual(boot_volume_id, expected_boot_vol_id)
2340 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2341 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2342 self.vimconn.cinder.volumes.create.assert_called_once_with(
2343 size=10,
2344 name="basicvmvda",
2345 imageRef=image_id,
2346 availability_zone=["nova"],
2347 )
2348 self.assertEqual(created_items, {f"volume:{volume_id2}": True})
2349
2350 def test_prepare_persistent_non_root_volumes_create(self):
2351 """Create persistent non-root volume."""
2352 self.vimconn.cinder = CopyingMock()
2353 self.vimconn.cinder.volumes.create.return_value.id = volume_id2
2354 vm_av_zone = ["nova"]
2355 base_disk_index = ord("a")
2356 disk = {"size": 10}
2357 block_device_mapping = {}
2358 existing_vim_volumes = []
2359 created_items = {}
2360 expected_block_device_mapping = {"vda": volume_id2}
2361 expected_existing_vim_volumes = []
2362 self.vimconn._prepare_non_root_persistent_volumes(
2363 name,
2364 disk,
2365 vm_av_zone,
2366 block_device_mapping,
2367 base_disk_index,
2368 existing_vim_volumes,
2369 created_items,
2370 )
2371
2372 self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
2373 self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
2374 self.vimconn.cinder.volumes.create.assert_called_once_with(
2375 size=10, name="basicvmvda", availability_zone=["nova"]
2376 )
2377 self.assertEqual(created_items, {f"volume:{volume_id2}": True})
2378
2379 def test_prepare_persistent_root_volumes_create_raise_exception(self):
2380 """Create persistent root volume raise exception."""
2381 self.vimconn.cinder.volumes.create.side_effect = Exception
2382 vm_av_zone = ["nova"]
2383 base_disk_index = ord("a")
2384 disk = {"size": 10, "image_id": image_id}
2385 block_device_mapping = {}
2386 existing_vim_volumes = []
2387 created_items = {}
2388
2389 with self.assertRaises(Exception):
2390 result = self.vimconn._prepare_persistent_root_volumes(
2391 name,
2392 vm_av_zone,
2393 disk,
2394 base_disk_index,
2395 block_device_mapping,
2396 existing_vim_volumes,
2397 created_items,
2398 )
2399
2400 self.assertEqual(result, None)
2401
2402 self.vimconn.cinder.volumes.create.assert_called_once_with(
2403 size=10,
2404 name="basicvmvda",
2405 imageRef=image_id,
2406 availability_zone=["nova"],
2407 )
2408 self.assertEqual(existing_vim_volumes, [])
2409 self.assertEqual(block_device_mapping, {})
2410 self.assertEqual(created_items, {})
2411
2412 def test_prepare_persistent_non_root_volumes_create_raise_exception(self):
2413 """Create persistent non-root volume raise exception."""
2414 self.vimconn.cinder.volumes.create.side_effect = Exception
2415 vm_av_zone = ["nova"]
2416 base_disk_index = ord("b")
2417 disk = {"size": 10}
2418 block_device_mapping = {}
2419 existing_vim_volumes = []
2420 created_items = {}
2421
2422 with self.assertRaises(Exception):
2423 self.vimconn._prepare_non_root_persistent_volumes(
2424 name,
2425 disk,
2426 vm_av_zone,
2427 block_device_mapping,
2428 base_disk_index,
2429 existing_vim_volumes,
2430 created_items,
2431 )
2432
2433 self.vimconn.cinder.volumes.create.assert_called_once_with(
2434 size=10, name="basicvmvdb", availability_zone=["nova"]
2435 )
2436 self.assertEqual(existing_vim_volumes, [])
2437 self.assertEqual(block_device_mapping, {})
2438 self.assertEqual(created_items, {})
2439
2440 @patch("time.sleep")
2441 def test_wait_for_created_volumes_availability_volume_status_available(
2442 self, mock_sleep
2443 ):
2444 """Created volume status is available."""
2445 elapsed_time = 5
2446 created_items = {f"volume:{volume_id2}": True}
2447 self.vimconn.cinder.volumes.get.return_value.status = "available"
2448
2449 result = self.vimconn._wait_for_created_volumes_availability(
2450 elapsed_time, created_items
2451 )
2452 self.assertEqual(result, elapsed_time)
2453 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2454 mock_sleep.assert_not_called()
2455
2456 @patch("time.sleep")
2457 def test_wait_for_existing_volumes_availability_volume_status_available(
2458 self, mock_sleep
2459 ):
2460 """Existing volume status is available."""
2461 elapsed_time = 5
2462 existing_vim_volumes = [{"id": volume_id2}]
2463 self.vimconn.cinder.volumes.get.return_value.status = "available"
2464
2465 result = self.vimconn._wait_for_existing_volumes_availability(
2466 elapsed_time, existing_vim_volumes
2467 )
2468 self.assertEqual(result, elapsed_time)
2469 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2470 mock_sleep.assert_not_called()
2471
2472 @patch("time.sleep")
2473 def test_wait_for_created_volumes_availability_status_processing_multiple_volumes(
2474 self, mock_sleep
2475 ):
2476 """Created volume status is processing."""
2477 elapsed_time = 5
2478 created_items = {
2479 f"volume:{volume_id2}": True,
2480 f"volume:{volume_id3}": True,
2481 }
2482 self.vimconn.cinder.volumes.get.side_effect = [
2483 Status("processing"),
2484 Status("available"),
2485 Status("available"),
2486 ]
2487
2488 result = self.vimconn._wait_for_created_volumes_availability(
2489 elapsed_time, created_items
2490 )
2491 self.assertEqual(result, 10)
2492 _call_mock_get_volumes = self.vimconn.cinder.volumes.get.call_args_list
2493 self.assertEqual(_call_mock_get_volumes[0][0], (volume_id2,))
2494 self.assertEqual(_call_mock_get_volumes[1][0], (volume_id2,))
2495 self.assertEqual(_call_mock_get_volumes[2][0], (volume_id3,))
2496 mock_sleep.assert_called_with(5)
2497 self.assertEqual(1, mock_sleep.call_count)
2498
2499 @patch("time.sleep")
2500 def test_wait_for_existing_volumes_availability_status_processing_multiple_volumes(
2501 self, mock_sleep
2502 ):
2503 """Existing volume status is processing."""
2504 elapsed_time = 5
2505 existing_vim_volumes = [
2506 {"id": volume_id2},
2507 {"id": "44e0e83-b9uu-4akk-t234-p9cc4811bd4a"},
2508 ]
2509 self.vimconn.cinder.volumes.get.side_effect = [
2510 Status("processing"),
2511 Status("available"),
2512 Status("available"),
2513 ]
2514
2515 result = self.vimconn._wait_for_existing_volumes_availability(
2516 elapsed_time, existing_vim_volumes
2517 )
2518 self.assertEqual(result, 10)
2519 _call_mock_get_volumes = self.vimconn.cinder.volumes.get.call_args_list
2520 self.assertEqual(_call_mock_get_volumes[0][0], (volume_id2,))
2521 self.assertEqual(_call_mock_get_volumes[1][0], (volume_id2,))
2522 self.assertEqual(
2523 _call_mock_get_volumes[2][0], ("44e0e83-b9uu-4akk-t234-p9cc4811bd4a",)
2524 )
2525 mock_sleep.assert_called_with(5)
2526 self.assertEqual(1, mock_sleep.call_count)
2527
2528 @patch("time.sleep")
2529 def test_wait_for_created_volumes_availability_volume_status_processing_timeout(
2530 self, mock_sleep
2531 ):
2532 """Created volume status is processing, elapsed time greater than timeout (1800)."""
2533 elapsed_time = 1805
2534 created_items = {f"volume:{volume_id2}": True}
2535 self.vimconn.cinder.volumes.get.side_effect = [
2536 Status("processing"),
2537 Status("processing"),
2538 ]
2539 with patch("time.sleep", mock_sleep):
2540 result = self.vimconn._wait_for_created_volumes_availability(
2541 elapsed_time, created_items
2542 )
2543 self.assertEqual(result, 1805)
2544 self.vimconn.cinder.volumes.get.assert_not_called()
2545 mock_sleep.assert_not_called()
2546
2547 @patch("time.sleep")
2548 def test_wait_for_existing_volumes_availability_volume_status_processing_timeout(
2549 self, mock_sleep
2550 ):
2551 """Exsiting volume status is processing, elapsed time greater than timeout (1800)."""
2552 elapsed_time = 1805
2553 existing_vim_volumes = [{"id": volume_id2}]
2554 self.vimconn.cinder.volumes.get.side_effect = [
2555 Status("processing"),
2556 Status("processing"),
2557 ]
2558
2559 result = self.vimconn._wait_for_existing_volumes_availability(
2560 elapsed_time, existing_vim_volumes
2561 )
2562 self.assertEqual(result, 1805)
2563 self.vimconn.cinder.volumes.get.assert_not_called()
2564 mock_sleep.assert_not_called()
2565
2566 @patch("time.sleep")
2567 def test_wait_for_created_volumes_availability_cinder_raise_exception(
2568 self, mock_sleep
2569 ):
2570 """Cinder get volumes raises exception for created volumes."""
2571 elapsed_time = 1000
2572 created_items = {f"volume:{volume_id2}": True}
2573 self.vimconn.cinder.volumes.get.side_effect = Exception
2574 with self.assertRaises(Exception):
2575 result = self.vimconn._wait_for_created_volumes_availability(
2576 elapsed_time, created_items
2577 )
2578 self.assertEqual(result, 1000)
2579 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2580 mock_sleep.assert_not_called()
2581
2582 @patch("time.sleep")
2583 def test_wait_for_existing_volumes_availability_cinder_raise_exception(
2584 self, mock_sleep
2585 ):
2586 """Cinder get volumes raises exception for existing volumes."""
2587 elapsed_time = 1000
2588 existing_vim_volumes = [{"id": volume_id2}]
2589 self.vimconn.cinder.volumes.get.side_effect = Exception
2590 with self.assertRaises(Exception):
2591 result = self.vimconn._wait_for_existing_volumes_availability(
2592 elapsed_time, existing_vim_volumes
2593 )
2594 self.assertEqual(result, 1000)
2595 self.vimconn.cinder.volumes.get.assert_called_with(volume_id2)
2596 mock_sleep.assert_not_called()
2597
2598 @patch("time.sleep")
2599 def test_wait_for_created_volumes_availability_no_volume_in_created_items(
2600 self, mock_sleep
2601 ):
2602 """Created_items dict does not have volume-id."""
2603 elapsed_time = 10
2604 created_items = {}
2605
2606 self.vimconn.cinder.volumes.get.side_effect = [None]
2607
2608 result = self.vimconn._wait_for_created_volumes_availability(
2609 elapsed_time, created_items
2610 )
2611 self.assertEqual(result, 10)
2612 self.vimconn.cinder.volumes.get.assert_not_called()
2613 mock_sleep.assert_not_called()
2614
2615 @patch("time.sleep")
2616 def test_wait_for_existing_volumes_availability_no_volume_in_existing_vim_volumes(
2617 self, mock_sleep
2618 ):
2619 """Existing_vim_volumes list does not have volume."""
2620 elapsed_time = 10
2621 existing_vim_volumes = []
2622
2623 self.vimconn.cinder.volumes.get.side_effect = [None]
2624
2625 result = self.vimconn._wait_for_existing_volumes_availability(
2626 elapsed_time, existing_vim_volumes
2627 )
2628 self.assertEqual(result, 10)
2629 self.vimconn.cinder.volumes.get.assert_not_called()
2630 mock_sleep.assert_not_called()
2631
2632 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2633 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2634 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2635 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2636 def test_prepare_disk_for_vm_instance(
2637 self,
2638 mock_existing_vol_availability,
2639 mock_created_vol_availability,
2640 mock_non_root_volumes,
2641 mock_root_volumes,
2642 ):
2643 """Prepare disks for VM instance successfully."""
2644 existing_vim_volumes = []
2645 created_items = {}
2646 block_device_mapping = {}
2647 vm_av_zone = ["nova"]
2648
2649 mock_root_volumes.return_value = root_vol_id
2650 mock_created_vol_availability.return_value = 10
2651 mock_existing_vol_availability.return_value = 15
2652 self.vimconn.cinder = CopyingMock()
2653
2654 self.vimconn._prepare_disk_for_vminstance(
2655 name,
2656 existing_vim_volumes,
2657 created_items,
2658 vm_av_zone,
2659 block_device_mapping,
2660 disk_list2,
2661 )
2662 self.vimconn.cinder.volumes.set_bootable.assert_called_once_with(
2663 root_vol_id, True
2664 )
2665 mock_created_vol_availability.assert_called_once_with(0, created_items)
2666 mock_existing_vol_availability.assert_called_once_with(10, existing_vim_volumes)
2667 self.assertEqual(mock_root_volumes.call_count, 1)
2668 self.assertEqual(mock_non_root_volumes.call_count, 1)
2669 mock_root_volumes.assert_called_once_with(
2670 name="basicvm",
2671 vm_av_zone=["nova"],
2672 disk={"size": 10, "image_id": image_id},
2673 base_disk_index=97,
2674 block_device_mapping={},
2675 existing_vim_volumes=[],
2676 created_items={},
2677 )
2678 mock_non_root_volumes.assert_called_once_with(
2679 name="basicvm",
2680 disk={"size": 20},
2681 vm_av_zone=["nova"],
2682 base_disk_index=98,
2683 block_device_mapping={},
2684 existing_vim_volumes=[],
2685 created_items={},
2686 )
2687
2688 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2689 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2690 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2691 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2692 def test_prepare_disk_for_vm_instance_timeout_exceeded(
2693 self,
2694 mock_existing_vol_availability,
2695 mock_created_vol_availability,
2696 mock_non_root_volumes,
2697 mock_root_volumes,
2698 ):
2699 """Timeout exceeded while waiting for disks."""
2700 existing_vim_volumes = []
2701 created_items = {}
2702 vm_av_zone = ["nova"]
2703 block_device_mapping = {}
2704
2705 mock_root_volumes.return_value = root_vol_id
2706 mock_created_vol_availability.return_value = 1700
2707 mock_existing_vol_availability.return_value = 1900
2708
2709 with self.assertRaises(VimConnException) as err:
2710 self.vimconn._prepare_disk_for_vminstance(
2711 name,
2712 existing_vim_volumes,
2713 created_items,
2714 vm_av_zone,
2715 block_device_mapping,
2716 disk_list2,
2717 )
2718 self.assertEqual(
2719 str(err.exception), "Timeout creating volumes for instance basicvm"
2720 )
2721 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2722 mock_created_vol_availability.assert_called_once_with(0, created_items)
2723 mock_existing_vol_availability.assert_called_once_with(
2724 1700, existing_vim_volumes
2725 )
2726 self.assertEqual(mock_root_volumes.call_count, 1)
2727 self.assertEqual(mock_non_root_volumes.call_count, 1)
2728 mock_root_volumes.assert_called_once_with(
2729 name="basicvm",
2730 vm_av_zone=["nova"],
2731 disk={"size": 10, "image_id": image_id},
2732 base_disk_index=97,
2733 block_device_mapping={},
2734 existing_vim_volumes=[],
2735 created_items={},
2736 )
2737 mock_non_root_volumes.assert_called_once_with(
2738 name="basicvm",
2739 disk={"size": 20},
2740 vm_av_zone=["nova"],
2741 base_disk_index=98,
2742 block_device_mapping={},
2743 existing_vim_volumes=[],
2744 created_items={},
2745 )
2746
2747 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2748 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2749 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2750 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2751 def test_prepare_disk_for_vm_instance_empty_disk_list(
2752 self,
2753 mock_existing_vol_availability,
2754 mock_created_vol_availability,
2755 mock_non_root_volumes,
2756 mock_root_volumes,
2757 ):
2758 """Disk list is empty."""
2759 existing_vim_volumes = []
2760 created_items = {}
2761 block_device_mapping = {}
2762 vm_av_zone = ["nova"]
2763 mock_created_vol_availability.return_value = 2
2764 mock_existing_vol_availability.return_value = 3
2765
2766 self.vimconn._prepare_disk_for_vminstance(
2767 name,
2768 existing_vim_volumes,
2769 created_items,
2770 vm_av_zone,
2771 block_device_mapping,
2772 disk_list,
2773 )
2774 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2775 mock_created_vol_availability.assert_called_once_with(0, created_items)
2776 mock_existing_vol_availability.assert_called_once_with(2, existing_vim_volumes)
2777 mock_root_volumes.assert_not_called()
2778 mock_non_root_volumes.assert_not_called()
2779
2780 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2781 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2782 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2783 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2784 def test_prepare_disk_for_vm_instance_persistent_root_volume_error(
2785 self,
2786 mock_existing_vol_availability,
2787 mock_created_vol_availability,
2788 mock_non_root_volumes,
2789 mock_root_volumes,
2790 ):
2791 """Persistent root volumes preparation raises error."""
2792 existing_vim_volumes = []
2793 created_items = {}
2794 vm_av_zone = ["nova"]
2795 block_device_mapping = {}
2796
2797 mock_root_volumes.side_effect = Exception()
2798 mock_created_vol_availability.return_value = 10
2799 mock_existing_vol_availability.return_value = 15
2800
2801 with self.assertRaises(Exception):
2802 self.vimconn._prepare_disk_for_vminstance(
2803 name,
2804 existing_vim_volumes,
2805 created_items,
2806 vm_av_zone,
2807 block_device_mapping,
2808 disk_list2,
2809 )
2810 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2811 mock_created_vol_availability.assert_not_called()
2812 mock_existing_vol_availability.assert_not_called()
2813 mock_root_volumes.assert_called_once_with(
2814 name="basicvm",
2815 vm_av_zone=["nova"],
2816 disk={"size": 10, "image_id": image_id},
2817 base_disk_index=97,
2818 block_device_mapping={},
2819 existing_vim_volumes=[],
2820 created_items={},
2821 )
2822 mock_non_root_volumes.assert_not_called()
2823
2824 @patch.object(vimconnector, "_prepare_persistent_root_volumes")
2825 @patch.object(vimconnector, "_prepare_non_root_persistent_volumes")
2826 @patch.object(vimconnector, "_wait_for_created_volumes_availability")
2827 @patch.object(vimconnector, "_wait_for_existing_volumes_availability")
2828 def test_prepare_disk_for_vm_instance_non_root_volume_error(
2829 self,
2830 mock_existing_vol_availability,
2831 mock_created_vol_availability,
2832 mock_non_root_volumes,
2833 mock_root_volumes,
2834 ):
2835 """Non-root volumes preparation raises error."""
2836 existing_vim_volumes = []
2837 created_items = {}
2838 vm_av_zone = ["nova"]
2839 block_device_mapping = {}
2840
2841 mock_root_volumes.return_value = root_vol_id
2842 mock_non_root_volumes.side_effect = Exception
2843
2844 with self.assertRaises(Exception):
2845 self.vimconn._prepare_disk_for_vminstance(
2846 name,
2847 existing_vim_volumes,
2848 created_items,
2849 vm_av_zone,
2850 block_device_mapping,
2851 disk_list2,
2852 )
2853 self.vimconn.cinder.volumes.set_bootable.assert_not_called()
2854 mock_created_vol_availability.assert_not_called()
2855 mock_existing_vol_availability.assert_not_called()
2856 self.assertEqual(mock_root_volumes.call_count, 1)
2857 self.assertEqual(mock_non_root_volumes.call_count, 1)
2858 mock_root_volumes.assert_called_once_with(
2859 name="basicvm",
2860 vm_av_zone=["nova"],
2861 disk={"size": 10, "image_id": image_id},
2862 base_disk_index=97,
2863 block_device_mapping={},
2864 existing_vim_volumes=[],
2865 created_items={},
2866 )
2867 mock_non_root_volumes.assert_called_once_with(
2868 name="basicvm",
2869 disk={"size": 20},
2870 vm_av_zone=["nova"],
2871 base_disk_index=98,
2872 block_device_mapping={},
2873 existing_vim_volumes=[],
2874 created_items={},
2875 )
2876
2877 def test_find_external_network_for_floating_ip_no_external_network(self):
2878 """External network could not be found."""
2879 self.vimconn.neutron.list_networks.return_value = {
2880 "networks": [
2881 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": False}
2882 ]
2883 }
2884 with self.assertRaises(VimConnException) as err:
2885 self.vimconn._find_the_external_network_for_floating_ip()
2886 self.assertEqual(
2887 str(err.exception),
2888 "Cannot create floating_ip automatically since no external network is present",
2889 )
2890
2891 def test_find_external_network_for_floating_one_external_network(self):
2892 """One external network has been found."""
2893 self.vimconn.neutron.list_networks.return_value = {
2894 "networks": [
2895 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": True}
2896 ]
2897 }
2898 expected_result = "408b73-r9cc-5a6a-a270-82cc4811bd4a"
2899 result = self.vimconn._find_the_external_network_for_floating_ip()
2900 self.assertEqual(result, expected_result)
2901
2902 def test_find_external_network_for_floating_neutron_raises_exception(self):
2903 """Neutron list networks raises exception."""
2904 self.vimconn.neutron.list_networks.side_effect = Exception
2905 with self.assertRaises(Exception):
2906 self.vimconn._find_the_external_network_for_floating_ip()
2907
2908 def test_find_external_network_for_floating_several_external_network(self):
2909 """Several exernal networks has been found."""
2910 self.vimconn.neutron.list_networks.return_value = {
2911 "networks": [
2912 {"id": "408b73-r9cc-5a6a-a270-82cc4811bd4a", "router:external": True},
2913 {"id": "608b73-y9cc-5a6a-a270-12cc4811bd4a", "router:external": True},
2914 ]
2915 }
2916 with self.assertRaises(VimConnException) as err:
2917 self.vimconn._find_the_external_network_for_floating_ip()
2918 self.assertEqual(
2919 str(err.exception),
2920 "Cannot create floating_ip automatically since multiple external networks are present",
2921 )
2922
2923 def test_neutron_create_float_ip(self):
2924 """Floating ip creation is successful."""
2925 param = {"net_id": "408b73-r9cc-5a6a-a270-p2cc4811bd9a"}
2926 created_items = {}
2927 self.vimconn.neutron.create_floatingip.return_value = {
2928 "floatingip": {"id": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2929 }
2930 expected_created_items = {
2931 "floating_ip:308b73-t9cc-1a6a-a270-12cc4811bd4a": True
2932 }
2933 self.vimconn._neutron_create_float_ip(param, created_items)
2934 self.assertEqual(created_items, expected_created_items)
2935
2936 def test_neutron_create_float_ip_exception_occured(self):
2937 """Floating ip could not be created."""
2938 param = {
2939 "floatingip": {
2940 "floating_network_id": "408b73-r9cc-5a6a-a270-p2cc4811bd9a",
2941 "tenant_id": "308b73-19cc-8a6a-a270-02cc4811bd9a",
2942 }
2943 }
2944 created_items = {}
2945 self.vimconn.neutron = CopyingMock()
2946 self.vimconn.neutron.create_floatingip.side_effect = Exception(
2947 "Neutron floating ip create exception occured."
2948 )
2949 with self.assertRaises(VimConnException) as err:
2950 self.vimconn._neutron_create_float_ip(param, created_items)
2951 self.assertEqual(created_items, {})
2952 self.assertEqual(
2953 str(err.exception),
2954 "Exception: Cannot create new floating_ip Neutron floating ip create exception occured.",
2955 )
2956
2957 @patch.object(vimconnector, "_neutron_create_float_ip")
2958 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2959 def test_create_floating_ip_pool_id_available(
2960 self, mock_find_ext_network, mock_create_float_ip
2961 ):
2962 """Floating ip creation, ip pool is available."""
2963 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
2964 created_items = {}
2965 expected_param = {
2966 "floatingip": {
2967 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2968 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2969 }
2970 }
2971 self.vimconn._create_floating_ip(floating_network, self.server, created_items)
2972 mock_find_ext_network.assert_not_called()
2973 mock_create_float_ip.assert_called_once_with(expected_param, {})
2974
2975 @patch.object(vimconnector, "_neutron_create_float_ip")
2976 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2977 def test_create_floating_ip_finding_pool_id(
2978 self, mock_find_ext_network, mock_create_float_ip
2979 ):
2980 """Floating ip creation, pool id need to be found."""
2981 floating_network = {"floating_ip": True}
2982 created_items = {}
2983 mock_find_ext_network.return_value = "308b73-t9cc-1a6a-a270-12cc4811bd4a"
2984 expected_param = {
2985 "floatingip": {
2986 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
2987 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
2988 }
2989 }
2990 self.vimconn._create_floating_ip(floating_network, self.server, created_items)
2991 mock_find_ext_network.assert_called_once()
2992 mock_create_float_ip.assert_called_once_with(expected_param, {})
2993
2994 @patch.object(vimconnector, "_neutron_create_float_ip")
2995 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
2996 def test_create_floating_ip_neutron_create_floating_ip_exception(
2997 self, mock_find_ext_network, mock_create_float_ip
2998 ):
2999 """Neutron creat floating ip raises error."""
3000 floating_network = {"floating_ip": True}
3001 created_items = {}
3002 mock_create_float_ip.side_effect = VimConnException(
3003 "Can not create floating ip."
3004 )
3005 mock_find_ext_network.return_value = "308b73-t9cc-1a6a-a270-12cc4811bd4a"
3006 expected_param = {
3007 "floatingip": {
3008 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3009 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
3010 }
3011 }
3012
3013 with self.assertRaises(VimConnException) as err:
3014 self.vimconn._create_floating_ip(
3015 floating_network, self.server, created_items
3016 )
3017 self.assertEqual(str(err.exception), "Can not create floating ip.")
3018 mock_find_ext_network.assert_called_once()
3019 mock_create_float_ip.assert_called_once_with(expected_param, {})
3020
3021 @patch.object(vimconnector, "_neutron_create_float_ip")
3022 @patch.object(vimconnector, "_find_the_external_network_for_floating_ip")
3023 def test_create_floating_ip_can_not_find_pool_id(
3024 self, mock_find_ext_network, mock_create_float_ip
3025 ):
3026 """Floating ip creation, pool id could not be found."""
3027 floating_network = {"floating_ip": True}
3028 created_items = {}
3029 mock_find_ext_network.side_effect = VimConnException(
3030 "Cannot create floating_ip automatically since no external network is present"
3031 )
3032 with self.assertRaises(VimConnException) as err:
3033 self.vimconn._create_floating_ip(
3034 floating_network, self.server, created_items
3035 )
3036 self.assertEqual(
3037 str(err.exception),
3038 "Cannot create floating_ip automatically since no external network is present",
3039 )
3040 mock_find_ext_network.assert_called_once()
3041 mock_create_float_ip.assert_not_called()
3042
3043 def test_find_floating_ip_get_free_floating_ip(self):
3044 """Get free floating ips successfully."""
3045 floating_ips = [
3046 {
3047 "tenant_id": "408b73-r9cc-5a6a-a270-82cc4811bd4a",
3048 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3049 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3050 }
3051 ]
3052 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3053 expected_result = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3054
3055 result = self.vimconn._find_floating_ip(
3056 self.server, floating_ips, floating_network
3057 )
3058 self.assertEqual(result, expected_result)
3059
3060 def test_find_floating_ip_different_floating_network_id(self):
3061 """Floating network id is different with floating_ip of floating network."""
3062 floating_ips = [
3063 {
3064 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3065 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3066 }
3067 ]
3068 floating_network = {"floating_ip": "508b73-t9cc-1a6a-a270-12cc4811bd4a"}
3069
3070 result = self.vimconn._find_floating_ip(
3071 self.server, floating_ips, floating_network
3072 )
3073 self.assertEqual(result, None)
3074
3075 def test_find_floating_ip_different_fip_tenant(self):
3076 """Items in floating_ips has port_id, tenant_is is not same with server tenant id."""
3077 floating_ips = [
3078 {
3079 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3080 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3081 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3082 "tenant_id": self.server.id,
3083 }
3084 ]
3085 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3086 mock_create_floating_ip = CopyingMock()
3087 with patch.object(vimconnector, "_create_floating_ip", mock_create_floating_ip):
3088 result = self.vimconn._find_floating_ip(
3089 self.server, floating_ips, floating_network
3090 )
3091 self.assertEqual(result, None)
3092
3093 @patch("time.sleep")
3094 def test_assign_floating_ip(self, mock_sleep):
3095 """Assign floating ip successfully."""
3096 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3097 floating_network = {"vim_id": floating_network_vim_id}
3098 fip = {
3099 "port_id": floating_network_vim_id,
3100 "floating_network_id": "p08b73-e9cc-5a6a-t270-82cc4811bd4a",
3101 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3102 "tenant_id": "k08b73-e9cc-5a6a-t270-82cc4811bd4a",
3103 }
3104 self.vimconn.neutron.update_floatingip.side_effect = None
3105 self.vimconn.neutron.show_floatingip.return_value = fip
3106 expected_result = fip
3107
3108 result = self.vimconn._assign_floating_ip(free_floating_ip, floating_network)
3109 self.assertEqual(result, expected_result)
3110 self.vimconn.neutron.update_floatingip.assert_called_once_with(
3111 free_floating_ip,
3112 {"floatingip": {"port_id": floating_network_vim_id}},
3113 )
3114 mock_sleep.assert_called_once_with(5)
3115 self.vimconn.neutron.show_floatingip.assert_called_once_with(free_floating_ip)
3116
3117 @patch("time.sleep")
3118 def test_assign_floating_ip_update_floating_ip_exception(self, mock_sleep):
3119 """Neutron update floating ip raises exception."""
3120 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3121 floating_network = {"vim_id": floating_network_vim_id}
3122 self.vimconn.neutron = CopyingMock()
3123 self.vimconn.neutron.update_floatingip.side_effect = Exception(
3124 "Floating ip is not updated."
3125 )
3126
3127 with self.assertRaises(Exception) as err:
3128 result = self.vimconn._assign_floating_ip(
3129 free_floating_ip, floating_network
3130 )
3131 self.assertEqual(result, None)
3132 self.assertEqual(str(err.exception), "Floating ip is not updated.")
3133
3134 self.vimconn.neutron.update_floatingip.assert_called_once_with(
3135 free_floating_ip,
3136 {"floatingip": {"port_id": floating_network_vim_id}},
3137 )
3138 mock_sleep.assert_not_called()
3139 self.vimconn.neutron.show_floatingip.assert_not_called()
3140
3141 @patch("time.sleep")
3142 def test_assign_floating_ip_show_floating_ip_exception(self, mock_sleep):
3143 """Neutron show floating ip raises exception."""
3144 free_floating_ip = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3145 floating_network = {"vim_id": floating_network_vim_id}
3146 self.vimconn.neutron.update_floatingip.side_effect = None
3147 self.vimconn.neutron.show_floatingip.side_effect = Exception(
3148 "Floating ip could not be shown."
3149 )
3150
3151 with self.assertRaises(Exception) as err:
3152 result = self.vimconn._assign_floating_ip(
3153 free_floating_ip, floating_network
3154 )
3155 self.assertEqual(result, None)
3156 self.assertEqual(str(err.exception), "Floating ip could not be shown.")
3157 self.vimconn.neutron.update_floatingip.assert_called_once_with(
3158 free_floating_ip,
3159 {"floatingip": {"port_id": floating_network_vim_id}},
3160 )
3161 mock_sleep.assert_called_once_with(5)
3162 self.vimconn.neutron.show_floatingip.assert_called_once_with(free_floating_ip)
3163
3164 @patch("random.shuffle")
3165 @patch.object(vimconnector, "_find_floating_ip")
3166 def test_get_free_floating_ip(self, mock_find_floating_ip, mock_shuffle):
3167 """Get free floating ip successfully."""
3168 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3169 created_items = {}
3170 floating_ips = [
3171 {
3172 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3173 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3174 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3175 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3176 },
3177 {
3178 "port_id": "508b73-r9cc-5a6a-5270-o2cc4811bd4a",
3179 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3180 "id": "208b73-o9cc-5a6a-a270-52cc4811bd8",
3181 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3182 },
3183 ]
3184 self.vimconn.neutron.list_floatingips.return_value = {
3185 "floatingips": floating_ips
3186 }
3187 mock_find_floating_ip.return_value = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3188 expected_result = "508b73-o9cc-5a6a-a270-72cc4811bd8"
3189
3190 result = self.vimconn._get_free_floating_ip(
3191 self.server, floating_network, created_items
3192 )
3193 self.assertEqual(result, expected_result)
3194 mock_shuffle.assert_called_once_with(floating_ips)
3195 mock_find_floating_ip.assert_called_once_with(
3196 self.server, floating_ips, floating_network, created_items
3197 )
3198
3199 @patch("random.shuffle")
3200 @patch.object(vimconnector, "_find_floating_ip")
3201 def test_get_free_floating_ip_list_floating_ip_exception(
3202 self, mock_find_floating_ip, mock_shuffle
3203 ):
3204 """Neutron list floating IPs raises exception."""
3205 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3206 created_items = {}
3207 self.vimconn.neutron = CopyingMock()
3208 self.vimconn.neutron.list_floatingips.side_effect = Exception(
3209 "Floating ips could not be listed."
3210 )
3211 with self.assertRaises(Exception) as err:
3212 result = self.vimconn._get_free_floating_ip(
3213 self.server, floating_network, created_items
3214 )
3215 self.assertEqual(result, None)
3216 self.assertEqual(str(err.exception), "Floating ips could not be listed.")
3217 mock_shuffle.assert_not_called()
3218 mock_find_floating_ip.assert_not_called()
3219
3220 @patch("random.shuffle")
3221 @patch.object(vimconnector, "_find_floating_ip")
3222 def test_get_free_floating_ip_find_floating_ip_exception(
3223 self, mock_find_floating_ip, mock_shuffle
3224 ):
3225 """_find_floating_ip method raises exception."""
3226 floating_network = {"floating_ip": "308b73-t9cc-1a6a-a270-12cc4811bd4a"}
3227 created_items = {}
3228 floating_ips = [
3229 {
3230 "port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3231 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3232 "id": "508b73-o9cc-5a6a-a270-72cc4811bd8",
3233 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3234 },
3235 {
3236 "port_id": "508b73-r9cc-5a6a-5270-o2cc4811bd4a",
3237 "floating_network_id": "308b73-t9cc-1a6a-a270-12cc4811bd4a",
3238 "id": "208b73-o9cc-5a6a-a270-52cc4811bd8",
3239 "tenant_id": "208b73-e9cc-5a6a-t270-82cc4811bd4a",
3240 },
3241 ]
3242 self.vimconn.neutron = CopyingMock()
3243 self.vimconn.neutron.list_floatingips.return_value = {
3244 "floatingips": floating_ips
3245 }
3246 mock_find_floating_ip.side_effect = Exception(
3247 "Free floating ip could not be found."
3248 )
3249
3250 with self.assertRaises(Exception) as err:
3251 result = self.vimconn._get_free_floating_ip(
3252 self.server, floating_network, created_items
3253 )
3254 self.assertEqual(result, None)
3255 self.assertEqual(str(err.exception), "Free floating ip could not be found.")
3256 mock_shuffle.assert_called_once_with(floating_ips)
3257 mock_find_floating_ip.assert_called_once_with(
3258 self.server, floating_ips, floating_network, created_items
3259 )
3260
3261 @patch.object(vimconnector, "_create_floating_ip")
3262 @patch.object(vimconnector, "_get_free_floating_ip")
3263 @patch.object(vimconnector, "_assign_floating_ip")
3264 def test_prepare_external_network_for_vm_instance(
3265 self,
3266 mock_assign_floating_ip,
3267 mock_get_free_floating_ip,
3268 mock_create_floating_ip,
3269 ):
3270 """Prepare external network successfully."""
3271 external_network = [
3272 {
3273 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3274 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3275 },
3276 ]
3277 created_items = {}
3278 vm_start_time = time_return_value
3279 mock_get_free_floating_ip.side_effect = ["y08b73-o9cc-1a6a-a270-12cc4811bd4u"]
3280 mock_assign_floating_ip.return_value = {
3281 "floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}
3282 }
3283 self.vimconn.neutron = CopyingMock()
3284 self.vimconn.nova = CopyingMock()
3285 self.vimconn.neutron.show_floatingip.return_value = {
3286 "floatingip": {"port_id": ""}
3287 }
3288
3289 self.vimconn._prepare_external_network_for_vminstance(
3290 external_network, self.server, created_items, vm_start_time
3291 )
3292
3293 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
3294 mock_get_free_floating_ip.assert_called_once_with(
3295 self.server,
3296 {
3297 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3298 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3299 },
3300 created_items,
3301 )
3302 self.vimconn.neutron.show_floatingip.assert_called_once_with(
3303 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3304 )
3305 self.vimconn.nova.servers.get.assert_not_called()
3306 mock_create_floating_ip.assert_not_called()
3307 mock_assign_floating_ip.assert_called_once_with(
3308 "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3309 {
3310 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3311 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3312 },
3313 )
3314
3315 @patch("time.time")
3316 @patch("time.sleep")
3317 @patch.object(vimconnector, "_create_floating_ip")
3318 @patch.object(vimconnector, "_get_free_floating_ip")
3319 @patch.object(vimconnector, "_assign_floating_ip")
3320 def test_prepare_external_network_for_vm_instance_no_free_floating_ip(
3321 self,
3322 mock_assign_floating_ip,
3323 mock_get_free_floating_ip,
3324 mock_create_floating_ip,
3325 mock_sleep,
3326 mock_time,
3327 ):
3328 """There is not any free floating ip."""
3329 floating_network = {
3330 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3331 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3332 }
3333 external_network = [floating_network]
3334
3335 created_items = {}
3336 vm_start_time = time_return_value
3337 mock_get_free_floating_ip.return_value = None
3338 mock_assign_floating_ip.return_value = {}
3339 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3340 self.vimconn.neutron.show_floatingip.return_value = {}
3341
3342 with self.assertRaises(KeyError):
3343 self.vimconn._prepare_external_network_for_vminstance(
3344 external_network, self.server, created_items, vm_start_time
3345 )
3346
3347 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3348 mock_get_free_floating_ip.assert_called_with(
3349 self.server,
3350 {
3351 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3352 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3353 },
3354 created_items,
3355 )
3356 self.vimconn.neutron.show_floatingip.assert_called_with(None)
3357 mock_sleep.assert_not_called()
3358 mock_time.assert_not_called()
3359 self.assertEqual(self.vimconn.nova.servers.get.call_count, 4)
3360 mock_create_floating_ip.assert_called_with(
3361 floating_network, self.server, created_items
3362 )
3363 self.assertEqual(mock_create_floating_ip.call_count, 4)
3364 mock_assign_floating_ip.assert_not_called()
3365 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3366
3367 @patch("time.time")
3368 @patch("time.sleep")
3369 @patch.object(vimconnector, "_create_floating_ip")
3370 @patch.object(vimconnector, "_get_free_floating_ip")
3371 @patch.object(vimconnector, "_assign_floating_ip")
3372 def test_prepare_external_network_for_vm_instance_no_free_fip_can_not_create_fip_exit_on_error_false(
3373 self,
3374 mock_assign_floating_ip,
3375 mock_get_free_floating_ip,
3376 mock_create_floating_ip,
3377 mock_sleep,
3378 mock_time,
3379 ):
3380 """There is not any free floating ip, create_floating ip method raise exception
3381 exit_on_floating_ip_error set to False."""
3382 floating_network = {
3383 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3384 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3385 "exit_on_floating_ip_error": False,
3386 }
3387 external_network = [floating_network]
3388
3389 created_items = {}
3390 vm_start_time = time_return_value
3391 mock_get_free_floating_ip.return_value = None
3392 mock_assign_floating_ip.return_value = {}
3393 mock_create_floating_ip.side_effect = VimConnException(
3394 "Can not create floating ip."
3395 )
3396 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3397 self.vimconn.neutron.show_floatingip.return_value = {}
3398
3399 self.vimconn._prepare_external_network_for_vminstance(
3400 external_network, self.server, created_items, vm_start_time
3401 )
3402 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
3403 mock_get_free_floating_ip.assert_called_with(
3404 self.server,
3405 {
3406 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3407 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3408 "exit_on_floating_ip_error": False,
3409 },
3410 created_items,
3411 )
3412 self.vimconn.neutron.show_floatingip.assert_not_called()
3413 mock_sleep.assert_not_called()
3414 mock_time.assert_not_called()
3415 self.vimconn.nova.servers.get.assert_not_called()
3416 mock_create_floating_ip.assert_called_with(
3417 floating_network, self.server, created_items
3418 )
3419 self.assertEqual(mock_create_floating_ip.call_count, 1)
3420 mock_assign_floating_ip.assert_not_called()
3421
3422 @patch("time.time")
3423 @patch("time.sleep")
3424 @patch.object(vimconnector, "_create_floating_ip")
3425 @patch.object(vimconnector, "_get_free_floating_ip")
3426 @patch.object(vimconnector, "_assign_floating_ip")
3427 def test_prepare_external_network_for_vm_instance_no_free_fip_can_not_create_fip_exit_on_error_true(
3428 self,
3429 mock_assign_floating_ip,
3430 mock_get_free_floating_ip,
3431 mock_create_floating_ip,
3432 mock_sleep,
3433 mock_time,
3434 ):
3435 """There is not any free floating ip, create_floating ip method raise exception
3436 exit_on_floating_ip_error set to False."""
3437 floating_network = {
3438 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3439 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3440 "exit_on_floating_ip_error": True,
3441 }
3442 external_network = [floating_network]
3443
3444 created_items = {}
3445 vm_start_time = time_return_value
3446 mock_get_free_floating_ip.return_value = None
3447 mock_assign_floating_ip.return_value = {}
3448 mock_create_floating_ip.side_effect = VimConnException(
3449 "Can not create floating ip."
3450 )
3451 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3452 self.vimconn.neutron.show_floatingip.return_value = {}
3453 with self.assertRaises(VimConnException):
3454 self.vimconn._prepare_external_network_for_vminstance(
3455 external_network, self.server, created_items, vm_start_time
3456 )
3457 self.assertEqual(mock_get_free_floating_ip.call_count, 1)
3458 mock_get_free_floating_ip.assert_called_with(
3459 self.server,
3460 {
3461 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3462 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3463 "exit_on_floating_ip_error": True,
3464 },
3465 created_items,
3466 )
3467 self.vimconn.neutron.show_floatingip.assert_not_called()
3468 mock_sleep.assert_not_called()
3469 mock_time.assert_not_called()
3470 self.vimconn.nova.servers.get.assert_not_called()
3471 mock_create_floating_ip.assert_called_with(
3472 floating_network, self.server, created_items
3473 )
3474 self.assertEqual(mock_create_floating_ip.call_count, 1)
3475 mock_assign_floating_ip.assert_not_called()
3476
3477 @patch.object(vimconnector, "_create_floating_ip")
3478 @patch.object(vimconnector, "_get_free_floating_ip")
3479 @patch.object(vimconnector, "_assign_floating_ip")
3480 def test_prepare_external_network_for_vm_instance_fip_has_port_id(
3481 self,
3482 mock_assign_floating_ip,
3483 mock_get_free_floating_ip,
3484 mock_create_floating_ip,
3485 ):
3486 """Neutron show floating ip return the fip with port_id and floating network vim_id
3487 is different from port_id."""
3488 floating_network = {
3489 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3490 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3491 }
3492 external_network = [floating_network]
3493 created_items = {}
3494 vm_start_time = 150
3495 mock_get_free_floating_ip.side_effect = [
3496 "t08b73-o9cc-1a6a-a270-12cc4811bd4u",
3497 "r08b73-o9cc-1a6a-a270-12cc4811bd4u",
3498 "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3499 ]
3500 mock_assign_floating_ip.side_effect = [
3501 {"floatingip": {"port_id": "k08b73-r9cc-5a6a-a270-82cc4811bd4a"}},
3502 {"floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}},
3503 ]
3504 self.vimconn.neutron = CopyingMock()
3505 self.vimconn.nova = CopyingMock()
3506 self.vimconn.neutron.show_floatingip.side_effect = [
3507 {"floatingip": {"port_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a"}},
3508 {"floatingip": {"port_id": ""}},
3509 {"floatingip": {"port_id": ""}},
3510 ]
3511 self.vimconn._prepare_external_network_for_vminstance(
3512 external_network, self.server, created_items, vm_start_time
3513 )
3514 self.assertEqual(mock_get_free_floating_ip.call_count, 3)
3515 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3516 self.assertEqual(
3517 _call_mock_get_free_floating_ip[0][0],
3518 (
3519 self.server,
3520 floating_network,
3521 created_items,
3522 ),
3523 )
3524 self.assertEqual(
3525 _call_mock_get_free_floating_ip[1][0],
3526 (
3527 self.server,
3528 floating_network,
3529 created_items,
3530 ),
3531 )
3532 self.assertEqual(
3533 _call_mock_get_free_floating_ip[2][0],
3534 (
3535 self.server,
3536 floating_network,
3537 created_items,
3538 ),
3539 )
3540 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 3)
3541 self.vimconn.nova.servers.get.assert_not_called()
3542 mock_create_floating_ip.assert_not_called()
3543 self.assertEqual(mock_assign_floating_ip.call_count, 2)
3544 _call_mock_assign_floating_ip = mock_assign_floating_ip.call_args_list
3545 self.assertEqual(
3546 _call_mock_assign_floating_ip[0][0],
3547 ("r08b73-o9cc-1a6a-a270-12cc4811bd4u", floating_network),
3548 )
3549 self.assertEqual(
3550 _call_mock_assign_floating_ip[1][0],
3551 ("y08b73-o9cc-1a6a-a270-12cc4811bd4u", floating_network),
3552 )
3553
3554 @patch("time.time")
3555 @patch("time.sleep")
3556 @patch.object(vimconnector, "_create_floating_ip")
3557 @patch.object(vimconnector, "_get_free_floating_ip")
3558 @patch.object(vimconnector, "_assign_floating_ip")
3559 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_vm_status_in_error(
3560 self,
3561 mock_assign_floating_ip,
3562 mock_get_free_floating_ip,
3563 mock_create_floating_ip,
3564 mock_sleep,
3565 mock_time,
3566 ):
3567 """Neutron show floating ip gives exception, exit_on_floating_ip_error set to True,
3568 VM status is in error."""
3569 floating_network = {
3570 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3571 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3572 "exit_on_floating_ip_error": True,
3573 }
3574 external_network = [floating_network]
3575 created_items = {}
3576 vm_start_time = time_return_value
3577
3578 mock_time.side_effect = [156570150, 156570800, 156571200]
3579
3580 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3581 self.vimconn.neutron.show_floatingip.side_effect = [
3582 Exception("Floating ip could not be shown.")
3583 ] * 4
3584 with self.assertRaises(Exception) as err:
3585 self.vimconn._prepare_external_network_for_vminstance(
3586 external_network, self.server, created_items, vm_start_time
3587 )
3588 self.assertEqual(
3589 str(err.exception),
3590 "Cannot create floating_ip: Exception Floating ip could not be shown.",
3591 )
3592
3593 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3594 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3595 self.assertEqual(
3596 _call_mock_get_free_floating_ip[0][0],
3597 (
3598 self.server,
3599 floating_network,
3600 created_items,
3601 ),
3602 )
3603 self.assertEqual(
3604 _call_mock_get_free_floating_ip[1][0],
3605 (
3606 self.server,
3607 floating_network,
3608 created_items,
3609 ),
3610 )
3611 self.assertEqual(
3612 _call_mock_get_free_floating_ip[2][0],
3613 (
3614 self.server,
3615 floating_network,
3616 created_items,
3617 ),
3618 )
3619 self.assertEqual(
3620 _call_mock_get_free_floating_ip[3][0],
3621 (
3622 self.server,
3623 floating_network,
3624 created_items,
3625 ),
3626 )
3627
3628 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3629 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3630 mock_create_floating_ip.assert_not_called()
3631 mock_assign_floating_ip.assert_not_called()
3632 mock_time.assert_not_called()
3633 mock_sleep.assert_not_called()
3634
3635 @patch("time.time")
3636 @patch("time.sleep")
3637 @patch.object(vimconnector, "_create_floating_ip")
3638 @patch.object(vimconnector, "_get_free_floating_ip")
3639 @patch.object(vimconnector, "_assign_floating_ip")
3640 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_vm_status_in_active(
3641 self,
3642 mock_assign_floating_ip,
3643 mock_get_free_floating_ip,
3644 mock_create_floating_ip,
3645 mock_sleep,
3646 mock_time,
3647 ):
3648 """Neutron show floating ip gives exception, exit_on_floating_ip_error is set to False,
3649 VM status is in active."""
3650 floating_network = {
3651 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3652 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3653 "exit_on_floating_ip_error": False,
3654 }
3655 external_network = [floating_network]
3656 created_items = {}
3657 vm_start_time = time_return_value
3658
3659 mock_time.side_effect = [156570150, 156570800, 156571200]
3660
3661 self.vimconn.nova.servers.get.return_value.status = "ACTIVE"
3662 self.vimconn.neutron.show_floatingip.side_effect = [
3663 Exception("Floating ip could not be shown.")
3664 ] * 4
3665
3666 self.vimconn._prepare_external_network_for_vminstance(
3667 external_network, self.server, created_items, vm_start_time
3668 )
3669 # self.assertEqual(str(err.exception), "Cannot create floating_ip")
3670
3671 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3672 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3673 self.assertEqual(
3674 _call_mock_get_free_floating_ip[0][0],
3675 (
3676 self.server,
3677 floating_network,
3678 created_items,
3679 ),
3680 )
3681 self.assertEqual(
3682 _call_mock_get_free_floating_ip[1][0],
3683 (
3684 self.server,
3685 floating_network,
3686 created_items,
3687 ),
3688 )
3689 self.assertEqual(
3690 _call_mock_get_free_floating_ip[2][0],
3691 (
3692 self.server,
3693 floating_network,
3694 created_items,
3695 ),
3696 )
3697 self.assertEqual(
3698 _call_mock_get_free_floating_ip[3][0],
3699 (
3700 self.server,
3701 floating_network,
3702 created_items,
3703 ),
3704 )
3705
3706 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3707 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3708 mock_create_floating_ip.assert_not_called()
3709 mock_assign_floating_ip.assert_not_called()
3710 mock_time.assert_not_called()
3711 mock_sleep.assert_not_called()
3712
3713 @patch("time.time")
3714 @patch("time.sleep")
3715 @patch.object(vimconnector, "_create_floating_ip")
3716 @patch.object(vimconnector, "_get_free_floating_ip")
3717 @patch.object(vimconnector, "_assign_floating_ip")
3718 def test_prepare_external_network_for_vm_instance_neutron_show_fip_exception_exit_on_error(
3719 self,
3720 mock_assign_floating_ip,
3721 mock_get_free_floating_ip,
3722 mock_create_floating_ip,
3723 mock_sleep,
3724 mock_time,
3725 ):
3726 """Neutron show floating ip gives exception, but exit_on_floating_ip_error is set to True.
3727 VM status is not ACTIVE or ERROR, server timeout happened."""
3728 floating_network = {
3729 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3730 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3731 "exit_on_floating_ip_error": True,
3732 }
3733 external_network = [floating_network]
3734 created_items = {}
3735 vm_start_time = time_return_value
3736 mock_get_free_floating_ip.side_effect = None
3737 mock_time.side_effect = [156571790, 156571795, 156571800, 156571805]
3738 self.vimconn.nova.servers.get.return_value.status = "OTHER"
3739 self.vimconn.neutron.show_floatingip.side_effect = [
3740 Exception("Floating ip could not be shown.")
3741 ] * 5
3742
3743 with self.assertRaises(VimConnException) as err:
3744 self.vimconn._prepare_external_network_for_vminstance(
3745 external_network, self.server, created_items, vm_start_time
3746 )
3747 self.assertEqual(
3748 str(err.exception),
3749 "Cannot create floating_ip: Exception Floating ip could not be shown.",
3750 )
3751
3752 self.assertEqual(mock_get_free_floating_ip.call_count, 3)
3753 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3754 self.assertEqual(
3755 _call_mock_get_free_floating_ip[0][0],
3756 (
3757 self.server,
3758 floating_network,
3759 created_items,
3760 ),
3761 )
3762 self.assertEqual(
3763 _call_mock_get_free_floating_ip[1][0],
3764 (
3765 self.server,
3766 floating_network,
3767 created_items,
3768 ),
3769 )
3770 self.assertEqual(
3771 _call_mock_get_free_floating_ip[2][0],
3772 (
3773 self.server,
3774 floating_network,
3775 created_items,
3776 ),
3777 )
3778
3779 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 3)
3780 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3781 mock_create_floating_ip.assert_not_called()
3782 mock_assign_floating_ip.assert_not_called()
3783 self.assertEqual(mock_time.call_count, 3)
3784 self.assertEqual(mock_sleep.call_count, 2)
3785
3786 @patch("time.time")
3787 @patch("time.sleep")
3788 @patch.object(vimconnector, "_create_floating_ip")
3789 @patch.object(vimconnector, "_get_free_floating_ip")
3790 @patch.object(vimconnector, "_assign_floating_ip")
3791 def test_prepare_external_network_for_vm_instance_assign_floating_ip_exception_exit_on_error(
3792 self,
3793 mock_assign_floating_ip,
3794 mock_get_free_floating_ip,
3795 mock_create_floating_ip,
3796 mock_sleep,
3797 mock_time,
3798 ):
3799 """Assign floating ip method gives exception, exit_on_floating_ip_error is set to True.
3800 VM status is in ERROR."""
3801 floating_network = {
3802 "floating_ip": "y08b73-o9cc-1a6a-a270-12cc4811bd4u",
3803 "vim_id": "608b73-r9cc-5a6a-a270-82cc4811bd4a",
3804 "exit_on_floating_ip_error": True,
3805 }
3806 external_network = [floating_network]
3807 created_items = {}
3808 vm_start_time = time_return_value
3809
3810 mock_get_free_floating_ip.side_effect = [
3811 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3812 ] * 4
3813
3814 mock_time.side_effect = [156571790, 156571795, 156571800, 156571805]
3815
3816 mock_assign_floating_ip.side_effect = [
3817 Exception("Floating ip could not be assigned.")
3818 ] * 4
3819
3820 self.vimconn.nova.servers.get.return_value.status = "ERROR"
3821 self.vimconn.neutron.show_floatingip.side_effect = [
3822 {"floatingip": {"port_id": ""}}
3823 ] * 4
3824
3825 with self.assertRaises(VimConnException) as err:
3826 self.vimconn._prepare_external_network_for_vminstance(
3827 external_network, self.server, created_items, vm_start_time
3828 )
3829 self.assertEqual(
3830 str(err.exception),
3831 "Cannot create floating_ip: Exception Floating ip could not be assigned.",
3832 )
3833
3834 self.assertEqual(mock_get_free_floating_ip.call_count, 4)
3835 _call_mock_get_free_floating_ip = mock_get_free_floating_ip.call_args_list
3836 self.assertEqual(
3837 _call_mock_get_free_floating_ip[0][0],
3838 (
3839 self.server,
3840 floating_network,
3841 created_items,
3842 ),
3843 )
3844 self.assertEqual(
3845 _call_mock_get_free_floating_ip[1][0],
3846 (
3847 self.server,
3848 floating_network,
3849 created_items,
3850 ),
3851 )
3852 self.assertEqual(
3853 _call_mock_get_free_floating_ip[2][0],
3854 (
3855 self.server,
3856 floating_network,
3857 created_items,
3858 ),
3859 )
3860
3861 self.assertEqual(self.vimconn.neutron.show_floatingip.call_count, 4)
3862 self.vimconn.neutron.show_floatingip.assert_called_with(
3863 "y08b73-o9cc-1a6a-a270-12cc4811bd4u"
3864 )
3865 self.assertEqual(self.vimconn.nova.servers.get.call_count, 4)
3866 self.vimconn.nova.servers.get.assert_called_with(self.server.id)
3867 mock_time.assert_not_called()
3868 mock_sleep.assert_not_called()
3869 mock_create_floating_ip.assert_not_called()
3870
3871 @patch("time.time")
3872 @patch("time.sleep")
3873 @patch.object(vimconnector, "_create_floating_ip")
3874 @patch.object(vimconnector, "_get_free_floating_ip")
3875 @patch.object(vimconnector, "_assign_floating_ip")
3876 def test_prepare_external_network_for_vm_instance_empty_external_network_list(
3877 self,
3878 mock_assign_floating_ip,
3879 mock_get_free_floating_ip,
3880 mock_create_floating_ip,
3881 mock_sleep,
3882 mock_time,
3883 ):
3884 """External network list is empty."""
3885 external_network = []
3886 created_items = {}
3887 vm_start_time = time_return_value
3888
3889 self.vimconn._prepare_external_network_for_vminstance(
3890 external_network, self.server, created_items, vm_start_time
3891 )
3892 mock_create_floating_ip.assert_not_called()
3893 mock_time.assert_not_called()
3894 mock_sleep.assert_not_called()
3895 mock_assign_floating_ip.assert_not_called()
3896 mock_get_free_floating_ip.assert_not_called()
3897 self.vimconn.neutron.show.show_floatingip.assert_not_called()
3898 self.vimconn.nova.servers.get.assert_not_called()
3899
3900 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3901 def test_update_port_security_for_vm_instance(self, mock_wait_for_vm):
3902 """no_secured_ports has port and the port has allow-address-pairs."""
3903 no_secured_ports = [(port2_id, "allow-address-pairs")]
3904
3905 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3906
3907 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3908
3909 self.vimconn.neutron.update_port.assert_called_once_with(
3910 port2_id,
3911 {"port": {"allowed_address_pairs": [{"ip_address": "0.0.0.0/0"}]}},
3912 )
3913
3914 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3915 def test_update_port_security_for_vm_instance_no_allowed_address_pairs(
3916 self, mock_wait_for_vm
3917 ):
3918 """no_secured_ports has port and the port does not have allow-address-pairs."""
3919 no_secured_ports = [(port2_id, "something")]
3920
3921 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3922
3923 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3924
3925 self.vimconn.neutron.update_port.assert_called_once_with(
3926 port2_id,
3927 {"port": {"port_security_enabled": False, "security_groups": None}},
3928 )
3929
3930 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3931 def test_update_port_security_for_vm_instance_wait_for_vm_raise_exception(
3932 self, mock_wait_for_vm
3933 ):
3934 """__wait_for_vm raises timeout exception."""
3935 no_secured_ports = [(port2_id, "something")]
3936
3937 mock_wait_for_vm.side_effect = VimConnException("Timeout waiting for instance.")
3938
3939 with self.assertRaises(VimConnException) as err:
3940 self.vimconn._update_port_security_for_vminstance(
3941 no_secured_ports, self.server
3942 )
3943 self.assertEqual(str(err.exception), "Timeout waiting for instance.")
3944
3945 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3946
3947 self.vimconn.neutron.update_port.assert_not_called()
3948
3949 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3950 def test_update_port_security_for_vm_instance_neutron_update_port_raise_exception(
3951 self, mock_wait_for_vm
3952 ):
3953 """neutron_update_port method raises exception."""
3954 no_secured_ports = [(port2_id, "something")]
3955
3956 self.vimconn.neutron.update_port.side_effect = Exception(
3957 "Port security could not be updated."
3958 )
3959
3960 with self.assertRaises(VimConnException) as err:
3961 self.vimconn._update_port_security_for_vminstance(
3962 no_secured_ports, self.server
3963 )
3964 self.assertEqual(
3965 str(err.exception),
3966 "It was not possible to disable port security for port 17472685-f67f-49fd-8722-eabb7692fc22",
3967 )
3968 mock_wait_for_vm.assert_called_once_with(self.server.id, "ACTIVE")
3969
3970 self.vimconn.neutron.update_port.assert_called_once_with(
3971 port2_id,
3972 {"port": {"port_security_enabled": False, "security_groups": None}},
3973 )
3974
3975 @patch.object(vimconnector, "_vimconnector__wait_for_vm")
3976 def test_update_port_security_for_vm_instance_empty_port_list(
3977 self, mock_wait_for_vm
3978 ):
3979 """no_secured_ports list does not have any ports."""
3980 no_secured_ports = []
3981
3982 self.vimconn._update_port_security_for_vminstance(no_secured_ports, self.server)
3983
3984 mock_wait_for_vm.assert_not_called()
3985
3986 self.vimconn.neutron.update_port.assert_not_called()
3987
3988 @patch("time.time")
3989 @patch.object(vimconnector, "_reload_connection")
3990 @patch.object(vimconnector, "_prepare_network_for_vminstance")
3991 @patch.object(vimconnector, "_create_user_data")
3992 @patch.object(vimconnector, "_get_vm_availability_zone")
3993 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
3994 @patch.object(vimconnector, "_update_port_security_for_vminstance")
3995 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
3996 @patch.object(vimconnector, "delete_vminstance")
3997 @patch.object(vimconnector, "_format_exception")
3998 def test_new_vm_instance(
3999 self,
4000 mock_format_exception,
4001 mock_delete_vm_instance,
4002 mock_prepare_external_network,
4003 mock_update_port_security,
4004 mock_prepare_disk_for_vm_instance,
4005 mock_get_vm_availability_zone,
4006 mock_create_user_data,
4007 mock_prepare_network_for_vm_instance,
4008 mock_reload_connection,
4009 mock_time,
4010 ):
4011 """New VM instance creation is successful."""
4012
4013 mock_create_user_data.return_value = True, "userdata"
4014
4015 mock_get_vm_availability_zone.return_value = "nova"
4016
4017 self.vimconn.nova.servers.create.return_value = self.server
4018
4019 mock_time.return_value = time_return_value
4020
4021 expected_result = self.server.id, {}
4022
4023 result = self.vimconn.new_vminstance(
4024 name,
4025 description,
4026 start,
4027 image_id,
4028 flavor_id,
4029 affinity_group_list,
4030 net_list,
4031 cloud_config,
4032 disk_list2,
4033 availability_zone_index,
4034 availability_zone_list,
4035 )
4036 self.assertEqual(result, expected_result)
4037
4038 mock_reload_connection.assert_called_once()
4039 mock_prepare_network_for_vm_instance.assert_called_once_with(
4040 name=name,
4041 net_list=net_list,
4042 created_items={},
4043 net_list_vim=[],
4044 external_network=[],
4045 no_secured_ports=[],
4046 )
4047 mock_create_user_data.assert_called_once_with(cloud_config)
4048 mock_get_vm_availability_zone.assert_called_once_with(
4049 availability_zone_index, availability_zone_list
4050 )
4051 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4052 name=name,
4053 existing_vim_volumes=[],
4054 created_items={},
4055 vm_av_zone="nova",
4056 block_device_mapping={},
4057 disk_list=disk_list2,
4058 )
4059 self.vimconn.nova.servers.create.assert_called_once_with(
4060 name=name,
4061 image=image_id,
4062 flavor=flavor_id,
4063 nics=[],
4064 security_groups="default",
4065 availability_zone="nova",
4066 key_name="my_keypair",
4067 userdata="userdata",
4068 config_drive=True,
4069 block_device_mapping={},
4070 scheduler_hints={},
4071 )
4072 mock_time.assert_called_once()
4073 mock_update_port_security.assert_called_once_with([], self.server)
4074 mock_prepare_external_network.assert_called_once_with(
4075 external_network=[],
4076 server=self.server,
4077 created_items={},
4078 vm_start_time=time_return_value,
4079 )
4080 mock_delete_vm_instance.assert_not_called()
4081 mock_format_exception.assert_not_called()
4082
4083 @patch("time.time")
4084 @patch.object(vimconnector, "_reload_connection")
4085 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4086 @patch.object(vimconnector, "_create_user_data")
4087 @patch.object(vimconnector, "_get_vm_availability_zone")
4088 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4089 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4090 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4091 @patch.object(vimconnector, "delete_vminstance")
4092 @patch.object(vimconnector, "_format_exception")
4093 def test_new_vm_instance_create_user_data_fails(
4094 self,
4095 mock_format_exception,
4096 mock_delete_vm_instance,
4097 mock_prepare_external_network,
4098 mock_update_port_security,
4099 mock_prepare_disk_for_vm_instance,
4100 mock_get_vm_availability_zone,
4101 mock_create_user_data,
4102 mock_prepare_network_for_vm_instance,
4103 mock_reload_connection,
4104 mock_time,
4105 ):
4106 """New VM instance creation failed because of user data creation failure."""
4107
4108 mock_create_user_data.side_effect = Exception(
4109 "User data could not be retrieved."
4110 )
4111
4112 mock_get_vm_availability_zone.return_value = "nova"
4113
4114 self.vimconn.nova.servers.create.return_value = self.server
4115
4116 mock_time.return_value = time_return_value
4117
4118 self.vimconn.new_vminstance(
4119 name,
4120 description,
4121 start,
4122 image_id,
4123 flavor_id,
4124 affinity_group_list,
4125 net_list,
4126 cloud_config,
4127 disk_list,
4128 availability_zone_index,
4129 availability_zone_list,
4130 )
4131
4132 mock_reload_connection.assert_called_once()
4133 mock_prepare_network_for_vm_instance.assert_called_once_with(
4134 name=name,
4135 net_list=net_list,
4136 created_items={},
4137 net_list_vim=[],
4138 external_network=[],
4139 no_secured_ports=[],
4140 )
4141 mock_create_user_data.assert_called_once_with(cloud_config)
4142 mock_get_vm_availability_zone.assert_not_called()
4143 mock_prepare_disk_for_vm_instance.assert_not_called()
4144 self.vimconn.nova.servers.create.assert_not_called()
4145 mock_time.assert_not_called()
4146 mock_update_port_security.assert_not_called()
4147 mock_prepare_external_network.assert_not_called()
4148 mock_delete_vm_instance.assert_called_once_with(None, {})
4149 mock_format_exception.assert_called_once()
4150 arg = mock_format_exception.call_args[0][0]
4151 self.assertEqual(str(arg), "User data could not be retrieved.")
4152
4153 @patch("time.time")
4154 @patch.object(vimconnector, "_reload_connection")
4155 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4156 @patch.object(vimconnector, "_create_user_data")
4157 @patch.object(vimconnector, "_get_vm_availability_zone")
4158 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4159 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4160 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4161 @patch.object(vimconnector, "delete_vminstance")
4162 @patch.object(vimconnector, "_format_exception")
4163 def test_new_vm_instance_external_network_exception(
4164 self,
4165 mock_format_exception,
4166 mock_delete_vm_instance,
4167 mock_prepare_external_network,
4168 mock_update_port_security,
4169 mock_prepare_disk_for_vm_instance,
4170 mock_get_vm_availability_zone,
4171 mock_create_user_data,
4172 mock_prepare_network_for_vm_instance,
4173 mock_reload_connection,
4174 mock_time,
4175 ):
4176 """New VM instance creation, external network connection has failed as floating
4177 ip could not be created."""
4178
4179 mock_create_user_data.return_value = True, "userdata"
4180
4181 mock_get_vm_availability_zone.return_value = "nova"
4182
4183 self.vimconn.nova.servers.create.return_value = self.server
4184
4185 mock_time.return_value = time_return_value
4186
4187 mock_prepare_external_network.side_effect = VimConnException(
4188 "Can not create floating ip."
4189 )
4190
4191 self.vimconn.new_vminstance(
4192 name,
4193 description,
4194 start,
4195 image_id,
4196 flavor_id,
4197 affinity_group_list,
4198 net_list,
4199 cloud_config,
4200 disk_list2,
4201 availability_zone_index,
4202 availability_zone_list,
4203 )
4204
4205 mock_reload_connection.assert_called_once()
4206 mock_prepare_network_for_vm_instance.assert_called_once_with(
4207 name=name,
4208 net_list=net_list,
4209 created_items={},
4210 net_list_vim=[],
4211 external_network=[],
4212 no_secured_ports=[],
4213 )
4214 mock_create_user_data.assert_called_once_with(cloud_config)
4215 mock_get_vm_availability_zone.assert_called_once_with(
4216 availability_zone_index, availability_zone_list
4217 )
4218 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4219 name=name,
4220 existing_vim_volumes=[],
4221 created_items={},
4222 vm_av_zone="nova",
4223 block_device_mapping={},
4224 disk_list=disk_list2,
4225 )
4226 self.vimconn.nova.servers.create.assert_called_once_with(
4227 name=name,
4228 image=image_id,
4229 flavor=flavor_id,
4230 nics=[],
4231 security_groups="default",
4232 availability_zone="nova",
4233 key_name="my_keypair",
4234 userdata="userdata",
4235 config_drive=True,
4236 block_device_mapping={},
4237 scheduler_hints={},
4238 )
4239 mock_time.assert_called_once()
4240 mock_update_port_security.assert_called_once_with([], self.server)
4241 mock_prepare_external_network.assert_called_once_with(
4242 external_network=[],
4243 server=self.server,
4244 created_items={},
4245 vm_start_time=time_return_value,
4246 )
4247 mock_delete_vm_instance.assert_called_once_with(self.server.id, {})
4248 mock_format_exception.assert_called_once()
4249 arg = mock_format_exception.call_args[0][0]
4250 self.assertEqual(str(arg), "Can not create floating ip.")
4251
4252 @patch("time.time")
4253 @patch.object(vimconnector, "_reload_connection")
4254 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4255 @patch.object(vimconnector, "_create_user_data")
4256 @patch.object(vimconnector, "_get_vm_availability_zone")
4257 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4258 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4259 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4260 @patch.object(vimconnector, "delete_vminstance")
4261 @patch.object(vimconnector, "_format_exception")
4262 def test_new_vm_instance_with_affinity_group(
4263 self,
4264 mock_format_exception,
4265 mock_delete_vm_instance,
4266 mock_prepare_external_network,
4267 mock_update_port_security,
4268 mock_prepare_disk_for_vm_instance,
4269 mock_get_vm_availability_zone,
4270 mock_create_user_data,
4271 mock_prepare_network_for_vm_instance,
4272 mock_reload_connection,
4273 mock_time,
4274 ):
4275 """New VM creation with affinity group."""
4276 affinity_group_list = [
4277 {"affinity_group_id": "38b73-e9cc-5a6a-t270-82cc4811bd4a"}
4278 ]
4279 mock_create_user_data.return_value = True, "userdata"
4280 mock_get_vm_availability_zone.return_value = "nova"
4281 self.vimconn.nova.servers.create.return_value = self.server
4282 mock_time.return_value = time_return_value
4283 expected_result = self.server.id, {}
4284
4285 result = self.vimconn.new_vminstance(
4286 name,
4287 description,
4288 start,
4289 image_id,
4290 flavor_id,
4291 affinity_group_list,
4292 net_list,
4293 cloud_config,
4294 disk_list2,
4295 availability_zone_index,
4296 availability_zone_list,
4297 )
4298 self.assertEqual(result, expected_result)
4299
4300 mock_reload_connection.assert_called_once()
4301 mock_prepare_network_for_vm_instance.assert_called_once_with(
4302 name=name,
4303 net_list=net_list,
4304 created_items={},
4305 net_list_vim=[],
4306 external_network=[],
4307 no_secured_ports=[],
4308 )
4309 mock_create_user_data.assert_called_once_with(cloud_config)
4310 mock_get_vm_availability_zone.assert_called_once_with(
4311 availability_zone_index, availability_zone_list
4312 )
4313 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4314 name=name,
4315 existing_vim_volumes=[],
4316 created_items={},
4317 vm_av_zone="nova",
4318 block_device_mapping={},
4319 disk_list=disk_list2,
4320 )
4321 self.vimconn.nova.servers.create.assert_called_once_with(
4322 name=name,
4323 image=image_id,
4324 flavor=flavor_id,
4325 nics=[],
4326 security_groups="default",
4327 availability_zone="nova",
4328 key_name="my_keypair",
4329 userdata="userdata",
4330 config_drive=True,
4331 block_device_mapping={},
4332 scheduler_hints={"group": "38b73-e9cc-5a6a-t270-82cc4811bd4a"},
4333 )
4334 mock_time.assert_called_once()
4335 mock_update_port_security.assert_called_once_with([], self.server)
4336 mock_prepare_external_network.assert_called_once_with(
4337 external_network=[],
4338 server=self.server,
4339 created_items={},
4340 vm_start_time=time_return_value,
4341 )
4342 mock_delete_vm_instance.assert_not_called()
4343 mock_format_exception.assert_not_called()
4344
4345 @patch("time.time")
4346 @patch.object(vimconnector, "_reload_connection")
4347 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4348 @patch.object(vimconnector, "_create_user_data")
4349 @patch.object(vimconnector, "_get_vm_availability_zone")
4350 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4351 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4352 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4353 @patch.object(vimconnector, "delete_vminstance")
4354 @patch.object(vimconnector, "_format_exception")
4355 def test_new_vm_instance_nova_server_create_failed(
4356 self,
4357 mock_format_exception,
4358 mock_delete_vm_instance,
4359 mock_prepare_external_network,
4360 mock_update_port_security,
4361 mock_prepare_disk_for_vm_instance,
4362 mock_get_vm_availability_zone,
4363 mock_create_user_data,
4364 mock_prepare_network_for_vm_instance,
4365 mock_reload_connection,
4366 mock_time,
4367 ):
4368 """New VM(server) creation failed."""
4369
4370 mock_create_user_data.return_value = True, "userdata"
4371
4372 mock_get_vm_availability_zone.return_value = "nova"
4373
4374 self.vimconn.nova.servers.create.side_effect = Exception(
4375 "Server could not be created."
4376 )
4377
4378 mock_time.return_value = time_return_value
4379
4380 self.vimconn.new_vminstance(
4381 name,
4382 description,
4383 start,
4384 image_id,
4385 flavor_id,
4386 affinity_group_list,
4387 net_list,
4388 cloud_config,
4389 disk_list2,
4390 availability_zone_index,
4391 availability_zone_list,
4392 )
4393
4394 mock_reload_connection.assert_called_once()
4395 mock_prepare_network_for_vm_instance.assert_called_once_with(
4396 name=name,
4397 net_list=net_list,
4398 created_items={},
4399 net_list_vim=[],
4400 external_network=[],
4401 no_secured_ports=[],
4402 )
4403 mock_create_user_data.assert_called_once_with(cloud_config)
4404 mock_get_vm_availability_zone.assert_called_once_with(
4405 availability_zone_index, availability_zone_list
4406 )
4407 mock_prepare_disk_for_vm_instance.assert_called_once_with(
4408 name=name,
4409 existing_vim_volumes=[],
4410 created_items={},
4411 vm_av_zone="nova",
4412 block_device_mapping={},
4413 disk_list=disk_list2,
4414 )
4415
4416 self.vimconn.nova.servers.create.assert_called_once_with(
4417 name=name,
4418 image=image_id,
4419 flavor=flavor_id,
4420 nics=[],
4421 security_groups="default",
4422 availability_zone="nova",
4423 key_name="my_keypair",
4424 userdata="userdata",
4425 config_drive=True,
4426 block_device_mapping={},
4427 scheduler_hints={},
4428 )
4429 mock_time.assert_not_called()
4430 mock_update_port_security.assert_not_called()
4431 mock_prepare_external_network.assert_not_called()
4432 mock_delete_vm_instance.assert_called_once_with(None, {})
4433 mock_format_exception.assert_called_once()
4434 arg = mock_format_exception.call_args[0][0]
4435 self.assertEqual(str(arg), "Server could not be created.")
4436
4437 @patch("time.time")
4438 @patch.object(vimconnector, "_reload_connection")
4439 @patch.object(vimconnector, "_prepare_network_for_vminstance")
4440 @patch.object(vimconnector, "_create_user_data")
4441 @patch.object(vimconnector, "_get_vm_availability_zone")
4442 @patch.object(vimconnector, "_prepare_disk_for_vminstance")
4443 @patch.object(vimconnector, "_update_port_security_for_vminstance")
4444 @patch.object(vimconnector, "_prepare_external_network_for_vminstance")
4445 @patch.object(vimconnector, "delete_vminstance")
4446 @patch.object(vimconnector, "_format_exception")
4447 def test_new_vm_instance_connection_exception(
4448 self,
4449 mock_format_exception,
4450 mock_delete_vm_instance,
4451 mock_prepare_external_network,
4452 mock_update_port_security,
4453 mock_prepare_disk_for_vm_instance,
4454 mock_get_vm_availability_zone,
4455 mock_create_user_data,
4456 mock_prepare_network_for_vm_instance,
4457 mock_reload_connection,
4458 mock_time,
4459 ):
4460 """Connection to Cloud API has failed."""
4461 mock_reload_connection.side_effect = Exception("Can not connect to Cloud APIs.")
4462 mock_create_user_data.return_value = True, "userdata"
4463 mock_get_vm_availability_zone.return_value = "nova"
4464 self.vimconn.nova.servers.create.return_value = self.server
4465 mock_time.return_value = time_return_value
4466
4467 self.vimconn.new_vminstance(
4468 name,
4469 description,
4470 start,
4471 image_id,
4472 flavor_id,
4473 affinity_group_list,
4474 net_list,
4475 cloud_config,
4476 disk_list,
4477 availability_zone_index,
4478 availability_zone_list,
4479 )
4480 mock_format_exception.assert_called_once()
4481 arg = mock_format_exception.call_args[0][0]
4482 self.assertEqual(str(arg), "Can not connect to Cloud APIs.")
4483 mock_reload_connection.assert_called_once()
4484 mock_prepare_network_for_vm_instance.assert_not_called()
4485 mock_create_user_data.assert_not_called()
4486 mock_get_vm_availability_zone.assert_not_called()
4487 mock_prepare_disk_for_vm_instance.assert_not_called()
4488 self.vimconn.nova.servers.create.assert_not_called()
4489 mock_time.assert_not_called()
4490 mock_update_port_security.assert_not_called()
4491 mock_prepare_external_network.assert_not_called()
4492 mock_delete_vm_instance.assert_called_once_with(None, {})
4493
4494 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
4495 def test_delete_vm_ports_attached_to_network_empty_created_items(
4496 self, mock_delete_ports_by_id_wth_neutron
4497 ):
4498 """Created_items is emtpty."""
4499 created_items = {}
4500 self.vimconn._delete_vm_ports_attached_to_network(created_items)
4501 self.vimconn.neutron.list_ports.assert_not_called()
4502 self.vimconn.neutron.delete_port.assert_not_called()
4503 mock_delete_ports_by_id_wth_neutron.assert_not_called()
4504
4505 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
4506 def test_delete_vm_ports_attached_to_network(
4507 self, mock_delete_ports_by_id_wth_neutron
4508 ):
4509 created_items = {
4510 "floating_ip:308b73-t9cc-1a6a-a270-12cc4811bd4a": True,
4511 f"volume:{volume_id2}": True,
4512 f"volume:{volume_id}": True,
4513 f"port:{port_id}": True,
4514 }
4515 self.vimconn._delete_vm_ports_attached_to_network(created_items)
4516 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}")
4517 self.vimconn.logger.error.assert_not_called()
4518
4519 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
4520 def test_delete_vm_ports_attached_to_network_wthout_port(
4521 self, mock_delete_ports_by_id_wth_neutron
4522 ):
4523 """Created_items does not have port."""
4524 created_items = {
4525 f"floating_ip:{floating_network_vim_id}": True,
4526 f"volume:{volume_id2}": True,
4527 f"volume:{volume_id}": True,
4528 }
4529 self.vimconn._delete_vm_ports_attached_to_network(created_items)
4530 mock_delete_ports_by_id_wth_neutron.assert_not_called()
4531 self.vimconn.logger.error.assert_not_called()
4532
4533 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
4534 def test_delete_vm_ports_attached_to_network_delete_port_raise_vimconnexception(
4535 self, mock_delete_ports_by_id_wth_neutron
4536 ):
4537 """_delete_ports_by_id_wth_neutron raises vimconnexception."""
4538 created_items = deepcopy(created_items_all_true)
4539 mock_delete_ports_by_id_wth_neutron.side_effect = VimConnException(
4540 "Can not delete port"
4541 )
4542 self.vimconn._delete_vm_ports_attached_to_network(created_items)
4543 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}")
4544 self.vimconn.logger.error.assert_called_once_with(
4545 "Error deleting port: VimConnException: Can not delete port"
4546 )
4547
4548 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
4549 def test_delete_vm_ports_attached_to_network_delete_port_raise_nvexception(
4550 self, mock_delete_ports_by_id_wth_neutron
4551 ):
4552 """_delete_ports_by_id_wth_neutron raises nvExceptions.ClientException."""
4553 created_items = deepcopy(created_items_all_true)
4554 mock_delete_ports_by_id_wth_neutron.side_effect = nvExceptions.ClientException(
4555 "Connection aborted."
4556 )
4557 self.vimconn._delete_vm_ports_attached_to_network(created_items)
4558 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}")
4559 self.vimconn.logger.error.assert_called_once_with(
4560 "Error deleting port: ClientException: Unknown Error (HTTP Connection aborted.)"
4561 )
4562
4563 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
4564 def test_delete_vm_ports_attached_to_network_delete_port_invalid_port_item(
4565 self, mock_delete_ports_by_id_wth_neutron
4566 ):
4567 """port item is invalid."""
4568 created_items = {
4569 f"floating_ip:{floating_network_vim_id}": True,
4570 f"volume:{volume_id2}": True,
4571 f"volume:{volume_id}": True,
4572 f"port:{port_id}:": True,
4573 }
4574 mock_delete_ports_by_id_wth_neutron.side_effect = VimConnException(
4575 "Port is not valid."
4576 )
4577 self.vimconn._delete_vm_ports_attached_to_network(created_items)
4578 mock_delete_ports_by_id_wth_neutron.assert_called_once_with(f"{port_id}:")
4579 self.vimconn.logger.error.assert_called_once_with(
4580 "Error deleting port: VimConnException: Port is not valid."
4581 )
4582
4583 @patch.object(vimconnector, "_delete_ports_by_id_wth_neutron")
4584 def test_delete_vm_ports_attached_to_network_delete_port_already_deleted(
4585 self, mock_delete_ports_by_id_wth_neutron
4586 ):
4587 """port is already deleted."""
4588 created_items = {
4589 f"floating_ip:{floating_network_vim_id}": True,
4590 f"volume:{volume_id2}": True,
4591 f"volume:{volume_id}": None,
4592 f"port:{port_id}": None,
4593 }
4594 self.vimconn._delete_vm_ports_attached_to_network(created_items)
4595 mock_delete_ports_by_id_wth_neutron.assert_not_called()
4596 self.vimconn.logger.error.assert_not_called()
4597
4598 def test_delete_floating_ip_by_id(self):
4599 created_items = {
4600 f"floating_ip:{floating_network_vim_id}": True,
4601 f"port:{port_id}": True,
4602 }
4603 expected_created_items = {
4604 f"floating_ip:{floating_network_vim_id}": None,
4605 f"port:{port_id}": True,
4606 }
4607 k_id = floating_network_vim_id
4608 k = f"floating_ip:{floating_network_vim_id}"
4609 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
4610 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
4611 self.assertEqual(created_items, expected_created_items)
4612
4613 def test_delete_floating_ip_by_id_floating_ip_already_deleted(self):
4614 """floating ip is already deleted."""
4615 created_items = {
4616 f"floating_ip:{floating_network_vim_id}": None,
4617 f"port:{port_id}": True,
4618 }
4619 k_id = floating_network_vim_id
4620 k = f"floating_ip:{floating_network_vim_id}"
4621 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
4622 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
4623 self.assertEqual(
4624 created_items,
4625 {
4626 f"floating_ip:{floating_network_vim_id}": None,
4627 f"port:{port_id}": True,
4628 },
4629 )
4630
4631 def test_delete_floating_ip_by_id_floating_ip_raises_nvexception(self):
4632 """netron delete floating ip raises nvExceptions.ClientException."""
4633 created_items = {
4634 f"floating_ip:{floating_network_vim_id}": True,
4635 f"port:{port_id}": True,
4636 }
4637 k_id = floating_network_vim_id
4638 k = f"floating_ip:{floating_network_vim_id}"
4639 self.vimconn.neutron.delete_floatingip.side_effect = (
4640 nvExceptions.ClientException("Client exception occured.")
4641 )
4642 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
4643 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
4644 self.assertEqual(
4645 created_items,
4646 {
4647 f"floating_ip:{floating_network_vim_id}": True,
4648 f"port:{port_id}": True,
4649 },
4650 )
4651 self.vimconn.logger.error.assert_called_once_with(
4652 "Error deleting floating ip: ClientException: Unknown Error (HTTP Client exception occured.)"
4653 )
4654
4655 def test_delete_floating_ip_by_id_floating_ip_raises_vimconnexception(self):
4656 """netron delete floating ip raises VimConnNotFoundException."""
4657 created_items = {
4658 f"floating_ip:{floating_network_vim_id}": True,
4659 f"port:{port_id}": True,
4660 }
4661 k_id = floating_network_vim_id
4662 k = f"floating_ip:{floating_network_vim_id}"
4663 self.vimconn.neutron.delete_floatingip.side_effect = VimConnNotFoundException(
4664 "Port id could not found."
4665 )
4666 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
4667 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
4668 self.assertEqual(
4669 created_items,
4670 {
4671 f"floating_ip:{floating_network_vim_id}": True,
4672 f"port:{port_id}": True,
4673 },
4674 )
4675 self.vimconn.logger.error.assert_called_once_with(
4676 "Error deleting floating ip: VimConnNotFoundException: Port id could not found."
4677 )
4678
4679 def test_delete_floating_ip_by_id_floating_ip_invalid_k_item(self):
4680 """invalid floating ip item."""
4681 created_items = {
4682 f"floating_ip:{floating_network_vim_id}": True,
4683 f"port:{port_id}": True,
4684 }
4685 expected_created_items = {
4686 f"floating_ip:{floating_network_vim_id}::": None,
4687 f"floating_ip:{floating_network_vim_id}": True,
4688 f"port:{port_id}": True,
4689 }
4690 k_id = floating_network_vim_id
4691 k = f"floating_ip:{floating_network_vim_id}::"
4692 self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
4693 self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
4694 self.assertEqual(created_items, expected_created_items)
4695
4696 def test_delete_volumes_by_id_with_cinder_volume_status_available(self):
4697 """volume status is available."""
4698 created_items = {
4699 f"floating_ip:{floating_network_vim_id}": True,
4700 f"volume:{volume_id2}": True,
4701 f"volume:{volume_id}": True,
4702 f"port:{port_id}": None,
4703 }
4704 expected_created_items = {
4705 f"floating_ip:{floating_network_vim_id}": True,
4706 f"volume:{volume_id2}": True,
4707 f"volume:{volume_id}": None,
4708 f"port:{port_id}": None,
4709 }
4710 volumes_to_hold = []
4711 k = f"volume:{volume_id}"
4712 k_id = volume_id
4713 self.vimconn.cinder.volumes.get.return_value.status = "available"
4714 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4715 k, k_id, volumes_to_hold, created_items
4716 )
4717 self.assertEqual(result, None)
4718 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4719 self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
4720 self.vimconn.logger.error.assert_not_called()
4721 self.assertEqual(created_items, expected_created_items)
4722
4723 def test_delete_volumes_by_id_with_cinder_volume_already_deleted(self):
4724 """volume is already deleted."""
4725 created_items = {
4726 f"floating_ip:{floating_network_vim_id}": True,
4727 f"volume:{volume_id2}": True,
4728 f"volume:{volume_id}": None,
4729 f"port:{port_id}": None,
4730 }
4731 expected_created_items = {
4732 f"floating_ip:{floating_network_vim_id}": True,
4733 f"volume:{volume_id2}": True,
4734 f"volume:{volume_id}": None,
4735 f"port:{port_id}": None,
4736 }
4737 volumes_to_hold = []
4738 k = f"volume:{volume_id}"
4739 k_id = volume_id
4740 self.vimconn.cinder.volumes.get.return_value.status = "available"
4741 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4742 k, k_id, volumes_to_hold, created_items
4743 )
4744 self.assertEqual(result, None)
4745 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4746 self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
4747 self.vimconn.logger.error.assert_not_called()
4748 self.assertEqual(created_items, expected_created_items)
4749
4750 def test_delete_volumes_by_id_with_cinder_get_volume_raise_exception(self):
4751 """cinder get volume raises exception."""
4752 created_items = {
4753 f"floating_ip:{floating_network_vim_id}": True,
4754 f"volume:{volume_id2}": True,
4755 f"volume:{volume_id}": True,
4756 f"port:{port_id}": None,
4757 }
4758 expected_created_items = {
4759 f"floating_ip:{floating_network_vim_id}": True,
4760 f"volume:{volume_id2}": True,
4761 f"volume:{volume_id}": True,
4762 f"port:{port_id}": None,
4763 }
4764 volumes_to_hold = []
4765 k = f"volume:{volume_id}"
4766 k_id = volume_id
4767 self.vimconn.cinder.volumes.get.side_effect = Exception(
4768 "Can not get volume status."
4769 )
4770 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4771 k, k_id, volumes_to_hold, created_items
4772 )
4773 self.assertEqual(result, None)
4774 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4775 self.vimconn.cinder.volumes.delete.assert_not_called()
4776 self.vimconn.logger.error.assert_called_once_with(
4777 "Error deleting volume: Exception: Can not get volume status."
4778 )
4779 self.assertEqual(created_items, expected_created_items)
4780
4781 def test_delete_volumes_by_id_with_cinder_delete_volume_raise_exception(self):
4782 """cinder delete volume raises exception."""
4783 created_items = {
4784 f"floating_ip:{floating_network_vim_id}": True,
4785 f"volume:{volume_id2}": True,
4786 f"volume:{volume_id}": True,
4787 f"port:{port_id}": None,
4788 }
4789 expected_created_items = {
4790 f"floating_ip:{floating_network_vim_id}": True,
4791 f"volume:{volume_id2}": True,
4792 f"volume:{volume_id}": True,
4793 f"port:{port_id}": None,
4794 }
4795 volumes_to_hold = []
4796 k = f"volume:{volume_id}"
4797 k_id = volume_id
4798 self.vimconn.cinder.volumes.get.return_value.status = "available"
4799 self.vimconn.cinder.volumes.delete.side_effect = nvExceptions.ClientException(
4800 "Connection aborted."
4801 )
4802 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4803 k, k_id, volumes_to_hold, created_items
4804 )
4805 self.assertEqual(result, None)
4806 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4807 self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
4808 self.vimconn.logger.error.assert_called_once_with(
4809 "Error deleting volume: ClientException: Unknown Error (HTTP Connection aborted.)"
4810 )
4811 self.assertEqual(created_items, expected_created_items)
4812
4813 def test_delete_volumes_by_id_with_cinder_volume_to_be_hold(self):
4814 """volume_to_hold has item."""
4815 created_items = {
4816 f"floating_ip:{floating_network_vim_id}": True,
4817 f"volume:{volume_id2}": True,
4818 f"volume:{volume_id}": True,
4819 f"port:{port_id}": None,
4820 }
4821 expected_created_items = {
4822 f"floating_ip:{floating_network_vim_id}": True,
4823 f"volume:{volume_id2}": True,
4824 f"volume:{volume_id}": True,
4825 f"port:{port_id}": None,
4826 }
4827 volumes_to_hold = [volume_id]
4828 k = f"volume:{volume_id}"
4829 k_id = volume_id
4830 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4831 k, k_id, volumes_to_hold, created_items
4832 )
4833 self.assertEqual(result, None)
4834 self.vimconn.cinder.volumes.get.assert_not_called()
4835 self.vimconn.cinder.volumes.delete.assert_not_called()
4836 self.vimconn.logger.error.assert_not_called()
4837 self.assertEqual(created_items, expected_created_items)
4838
4839 def test_delete_volumes_by_id_with_cinder_volume_status_not_available(self):
4840 """volume status is not available."""
4841 created_items = {
4842 f"floating_ip:{floating_network_vim_id}": True,
4843 f"volume:{volume_id2}": True,
4844 f"volume:{volume_id}": True,
4845 f"port:{port_id}": None,
4846 }
4847 expected_created_items = {
4848 f"floating_ip:{floating_network_vim_id}": True,
4849 f"volume:{volume_id2}": True,
4850 f"volume:{volume_id}": True,
4851 f"port:{port_id}": None,
4852 }
4853 volumes_to_hold = []
4854 k = f"volume:{volume_id}"
4855 k_id = volume_id
4856 self.vimconn.cinder.volumes.get.return_value.status = "unavailable"
4857 result = self.vimconn._delete_volumes_by_id_wth_cinder(
4858 k, k_id, volumes_to_hold, created_items
4859 )
4860 self.assertEqual(result, True)
4861 self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
4862 self.vimconn.cinder.volumes.delete.assert_not_called()
4863 self.vimconn.logger.error.assert_not_called()
4864 self.assertEqual(created_items, expected_created_items)
4865
4866 def test_delete_ports_by_id_by_neutron(self):
4867 """neutron delete ports."""
4868 k_id = port_id
4869 self.vimconn.neutron.list_ports.return_value = {
4870 "ports": [{"id": port_id}, {"id": port2_id}]
4871 }
4872
4873 self.vimconn._delete_ports_by_id_wth_neutron(k_id)
4874 self.vimconn.neutron.list_ports.assert_called_once()
4875 self.vimconn.neutron.delete_port.assert_called_once_with(k_id)
4876 self.vimconn.logger.error.assert_not_called()
4877
4878 def test_delete_ports_by_id_by_neutron_id_not_in_port_list(self):
4879 """port id not in the port list."""
4880 k_id = volume_id
4881 self.vimconn.neutron.list_ports.return_value = {
4882 "ports": [{"id": port_id}, {"id": port2_id}]
4883 }
4884
4885 self.vimconn._delete_ports_by_id_wth_neutron(k_id)
4886 self.vimconn.neutron.list_ports.assert_called_once()
4887 self.vimconn.neutron.delete_port.assert_not_called()
4888 self.vimconn.logger.error.assert_not_called()
4889
4890 def test_delete_ports_by_id_by_neutron_list_port_raise_exception(self):
4891 """neutron list port raises exception."""
4892 k_id = port_id
4893 self.vimconn.neutron.list_ports.side_effect = nvExceptions.ClientException(
4894 "Connection aborted."
4895 )
4896 self.vimconn._delete_ports_by_id_wth_neutron(k_id)
4897 self.vimconn.neutron.list_ports.assert_called_once()
4898 self.vimconn.neutron.delete_port.assert_not_called()
4899 self.vimconn.logger.error.assert_called_once_with(
4900 "Error deleting port: ClientException: Unknown Error (HTTP Connection aborted.)"
4901 )
4902
4903 def test_delete_ports_by_id_by_neutron_delete_port_raise_exception(self):
4904 """neutron delete port raises exception."""
4905 k_id = port_id
4906 self.vimconn.neutron.list_ports.return_value = {
4907 "ports": [{"id": port_id}, {"id": port2_id}]
4908 }
4909 self.vimconn.neutron.delete_port.side_effect = nvExceptions.ClientException(
4910 "Connection aborted."
4911 )
4912 self.vimconn._delete_ports_by_id_wth_neutron(k_id)
4913 self.vimconn.neutron.list_ports.assert_called_once()
4914 self.vimconn.neutron.delete_port.assert_called_once_with(k_id)
4915 self.vimconn.logger.error.assert_called_once_with(
4916 "Error deleting port: ClientException: Unknown Error (HTTP Connection aborted.)"
4917 )
4918
4919 def test_get_item_name_id(self):
4920 """Get name and id successfully."""
4921 k = f"some:{port_id}"
4922 result = self.vimconn._get_item_name_id(k)
4923 self.assertEqual(result, ("some", f"{port_id}"))
4924
4925 def test_get_item_name_id_wthout_semicolon(self):
4926 """Does not have seperator."""
4927 k = f"some{port_id}"
4928 result = self.vimconn._get_item_name_id(k)
4929 self.assertEqual(result, (f"some{port_id}", ""))
4930
4931 def test_get_item_name_id_empty_string(self):
4932 """Empty string."""
4933 k = ""
4934 result = self.vimconn._get_item_name_id(k)
4935 self.assertEqual(result, ("", ""))
4936
4937 def test_get_item_name_id_k_is_none(self):
4938 """item is None."""
4939 k = None
4940 with self.assertRaises(AttributeError):
4941 self.vimconn._get_item_name_id(k)
4942
4943 @patch.object(vimconnector, "_get_item_name_id")
4944 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4945 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4946 def test_delete_created_items(
4947 self,
4948 mock_delete_floating_ip_by_id,
4949 mock_delete_volumes_by_id_wth_cinder,
4950 mock_get_item_name_id,
4951 ):
4952 """Created items has floating ip and volume."""
4953 created_items = {
4954 f"floating_ip:{floating_network_vim_id}": True,
4955 f"volume:{volume_id}": True,
4956 f"port:{port_id}": None,
4957 }
4958 mock_get_item_name_id.side_effect = [
4959 ("floating_ip", f"{floating_network_vim_id}"),
4960 ("volume", f"{volume_id}"),
4961 ]
4962 mock_delete_volumes_by_id_wth_cinder.return_value = True
4963 volumes_to_hold = []
4964 keep_waiting = False
4965 result = self.vimconn._delete_created_items(
4966 created_items, volumes_to_hold, keep_waiting
4967 )
4968 self.assertEqual(result, True)
4969 self.assertEqual(mock_get_item_name_id.call_count, 2)
4970 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
4971 f"volume:{volume_id}", f"{volume_id}", [], created_items
4972 )
4973 mock_delete_floating_ip_by_id.assert_called_once_with(
4974 f"floating_ip:{floating_network_vim_id}",
4975 f"{floating_network_vim_id}",
4976 created_items,
4977 )
4978 self.vimconn.logger.error.assert_not_called()
4979
4980 @patch.object(vimconnector, "_get_item_name_id")
4981 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
4982 @patch.object(vimconnector, "_delete_floating_ip_by_id")
4983 def test_delete_created_items_wth_volumes_to_hold(
4984 self,
4985 mock_delete_floating_ip_by_id,
4986 mock_delete_volumes_by_id_wth_cinder,
4987 mock_get_item_name_id,
4988 ):
4989 """Created items has floating ip and volume and volumes_to_hold has items."""
4990 created_items = {
4991 f"floating_ip:{floating_network_vim_id}": True,
4992 f"volume:{volume_id}": True,
4993 f"port:{port_id}": None,
4994 }
4995 mock_get_item_name_id.side_effect = [
4996 ("floating_ip", f"{floating_network_vim_id}"),
4997 ("volume", f"{volume_id}"),
4998 ]
4999 mock_delete_volumes_by_id_wth_cinder.return_value = True
5000 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5001 keep_waiting = False
5002 result = self.vimconn._delete_created_items(
5003 created_items, volumes_to_hold, keep_waiting
5004 )
5005 self.assertEqual(result, True)
5006 self.assertEqual(mock_get_item_name_id.call_count, 2)
5007 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
5008 f"volume:{volume_id}", f"{volume_id}", volumes_to_hold, created_items
5009 )
5010 mock_delete_floating_ip_by_id.assert_called_once_with(
5011 f"floating_ip:{floating_network_vim_id}",
5012 f"{floating_network_vim_id}",
5013 created_items,
5014 )
5015 self.vimconn.logger.error.assert_not_called()
5016
5017 @patch.object(vimconnector, "_get_item_name_id")
5018 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
5019 @patch.object(vimconnector, "_delete_floating_ip_by_id")
5020 def test_delete_created_items_wth_keep_waiting_true(
5021 self,
5022 mock_delete_floating_ip_by_id,
5023 mock_delete_volumes_by_id_wth_cinder,
5024 mock_get_item_name_id,
5025 ):
5026 """Keep waiting initial value is True."""
5027 created_items = {
5028 f"floating_ip:{floating_network_vim_id}": True,
5029 f"volume:{volume_id}": True,
5030 f"port:{port_id}": None,
5031 }
5032 mock_get_item_name_id.side_effect = [
5033 ("floating_ip", f"{floating_network_vim_id}"),
5034 ("volume", f"{volume_id}"),
5035 ]
5036 mock_delete_volumes_by_id_wth_cinder.return_value = False
5037 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5038 keep_waiting = True
5039 result = self.vimconn._delete_created_items(
5040 created_items, volumes_to_hold, keep_waiting
5041 )
5042 self.assertEqual(result, True)
5043 self.assertEqual(mock_get_item_name_id.call_count, 2)
5044 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
5045 f"volume:{volume_id}", f"{volume_id}", volumes_to_hold, created_items
5046 )
5047 mock_delete_floating_ip_by_id.assert_called_once_with(
5048 f"floating_ip:{floating_network_vim_id}",
5049 f"{floating_network_vim_id}",
5050 created_items,
5051 )
5052 self.vimconn.logger.error.assert_not_called()
5053
5054 @patch.object(vimconnector, "_get_item_name_id")
5055 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
5056 @patch.object(vimconnector, "_delete_floating_ip_by_id")
5057 def test_delete_created_items_delete_vol_raises(
5058 self,
5059 mock_delete_floating_ip_by_id,
5060 mock_delete_volumes_by_id_wth_cinder,
5061 mock_get_item_name_id,
5062 ):
5063 """Delete volume raises exception."""
5064 created_items = {
5065 f"floating_ip:{floating_network_vim_id}": True,
5066 f"volume:{volume_id}": True,
5067 f"port:{port_id}": None,
5068 }
5069 mock_get_item_name_id.side_effect = [
5070 ("floating_ip", f"{floating_network_vim_id}"),
5071 ("volume", f"{volume_id}"),
5072 ]
5073 mock_delete_volumes_by_id_wth_cinder.side_effect = ConnectionError(
5074 "Connection failed."
5075 )
5076 volumes_to_hold = []
5077 keep_waiting = False
5078 result = self.vimconn._delete_created_items(
5079 created_items, volumes_to_hold, keep_waiting
5080 )
5081 self.assertEqual(result, False)
5082 self.assertEqual(mock_get_item_name_id.call_count, 2)
5083 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
5084 f"volume:{volume_id}", f"{volume_id}", [], created_items
5085 )
5086 mock_delete_floating_ip_by_id.assert_called_once_with(
5087 f"floating_ip:{floating_network_vim_id}",
5088 f"{floating_network_vim_id}",
5089 created_items,
5090 )
5091 self.vimconn.logger.error.assert_called_once_with(
5092 "Error deleting volume:ac408b73-b9cc-4a6a-a270-82cc4811bd4a: Connection failed."
5093 )
5094
5095 @patch.object(vimconnector, "_get_item_name_id")
5096 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
5097 @patch.object(vimconnector, "_delete_floating_ip_by_id")
5098 def test_delete_created_items_delete_fip_raises(
5099 self,
5100 mock_delete_floating_ip_by_id,
5101 mock_delete_volumes_by_id_wth_cinder,
5102 mock_get_item_name_id,
5103 ):
5104 """Delete floating ip raises exception."""
5105 created_items = {
5106 f"floating_ip:{floating_network_vim_id}": True,
5107 f"volume:{volume_id}": True,
5108 f"port:{port_id}": None,
5109 }
5110 mock_get_item_name_id.side_effect = [
5111 ("floating_ip", f"{floating_network_vim_id}"),
5112 ("volume", f"{volume_id}"),
5113 ]
5114 mock_delete_volumes_by_id_wth_cinder.return_value = False
5115 mock_delete_floating_ip_by_id.side_effect = ConnectionError(
5116 "Connection failed."
5117 )
5118 volumes_to_hold = []
5119 keep_waiting = True
5120 result = self.vimconn._delete_created_items(
5121 created_items, volumes_to_hold, keep_waiting
5122 )
5123 self.assertEqual(result, True)
5124 self.assertEqual(mock_get_item_name_id.call_count, 2)
5125 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
5126 f"volume:{volume_id}", f"{volume_id}", [], created_items
5127 )
5128 mock_delete_floating_ip_by_id.assert_called_once_with(
5129 f"floating_ip:{floating_network_vim_id}",
5130 f"{floating_network_vim_id}",
5131 created_items,
5132 )
5133 self.vimconn.logger.error.assert_called_once_with(
5134 "Error deleting floating_ip:108b73-e9cc-5a6a-t270-82cc4811bd4a: Connection failed."
5135 )
5136
5137 @patch.object(vimconnector, "_get_item_name_id")
5138 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
5139 @patch.object(vimconnector, "_delete_floating_ip_by_id")
5140 def test_delete_created_items_get_item_name_raises(
5141 self,
5142 mock_delete_floating_ip_by_id,
5143 mock_delete_volumes_by_id_wth_cinder,
5144 mock_get_item_name_id,
5145 ):
5146 """Get item, name raises exception."""
5147 created_items = {
5148 3: True,
5149 f"volume{volume_id}": True,
5150 f"port:{port_id}": None,
5151 }
5152 mock_get_item_name_id.side_effect = [
5153 TypeError("Invalid Type"),
5154 AttributeError("Invalid attribute"),
5155 ]
5156 volumes_to_hold = []
5157 keep_waiting = False
5158 result = self.vimconn._delete_created_items(
5159 created_items, volumes_to_hold, keep_waiting
5160 )
5161 self.assertEqual(result, False)
5162 self.assertEqual(mock_get_item_name_id.call_count, 2)
5163 mock_delete_volumes_by_id_wth_cinder.assert_not_called()
5164 mock_delete_floating_ip_by_id.assert_not_called()
5165 _call_logger = self.vimconn.logger.error.call_args_list
5166 self.assertEqual(_call_logger[0][0], ("Error deleting 3: Invalid Type",))
5167 self.assertEqual(
5168 _call_logger[1][0],
5169 (f"Error deleting volume{volume_id}: Invalid attribute",),
5170 )
5171
5172 @patch.object(vimconnector, "_get_item_name_id")
5173 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
5174 @patch.object(vimconnector, "_delete_floating_ip_by_id")
5175 def test_delete_created_items_no_fip_wth_port(
5176 self,
5177 mock_delete_floating_ip_by_id,
5178 mock_delete_volumes_by_id_wth_cinder,
5179 mock_get_item_name_id,
5180 ):
5181 """Created items has port, does not have floating ip."""
5182 created_items = {
5183 f"volume:{volume_id}": True,
5184 f"port:{port_id}": True,
5185 }
5186 mock_get_item_name_id.side_effect = [
5187 ("volume", f"{volume_id}"),
5188 ("port", f"{port_id}"),
5189 ]
5190 mock_delete_volumes_by_id_wth_cinder.return_value = False
5191 volumes_to_hold = []
5192 keep_waiting = False
5193 result = self.vimconn._delete_created_items(
5194 created_items, volumes_to_hold, keep_waiting
5195 )
5196 self.assertEqual(result, False)
5197 self.assertEqual(mock_get_item_name_id.call_count, 2)
5198 mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
5199 f"volume:{volume_id}", f"{volume_id}", [], created_items
5200 )
5201 mock_delete_floating_ip_by_id.assert_not_called()
5202 self.vimconn.logger.error.assert_not_called()
5203
5204 @patch.object(vimconnector, "_get_item_name_id")
5205 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
5206 @patch.object(vimconnector, "_delete_floating_ip_by_id")
5207 def test_delete_created_items_no_volume(
5208 self,
5209 mock_delete_floating_ip_by_id,
5210 mock_delete_volumes_by_id_wth_cinder,
5211 mock_get_item_name_id,
5212 ):
5213 """Created items does not have volume."""
5214 created_items = {
5215 f"floating_ip:{floating_network_vim_id}": True,
5216 f"port:{port_id}": None,
5217 }
5218 mock_get_item_name_id.side_effect = [
5219 ("floating_ip", f"{floating_network_vim_id}")
5220 ]
5221 volumes_to_hold = []
5222 keep_waiting = False
5223 result = self.vimconn._delete_created_items(
5224 created_items, volumes_to_hold, keep_waiting
5225 )
5226 self.assertEqual(result, False)
5227 self.assertEqual(mock_get_item_name_id.call_count, 1)
5228 mock_delete_volumes_by_id_wth_cinder.assert_not_called()
5229 mock_delete_floating_ip_by_id.assert_called_once_with(
5230 f"floating_ip:{floating_network_vim_id}",
5231 f"{floating_network_vim_id}",
5232 created_items,
5233 )
5234 self.vimconn.logger.error.assert_not_called()
5235
5236 @patch.object(vimconnector, "_get_item_name_id")
5237 @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
5238 @patch.object(vimconnector, "_delete_floating_ip_by_id")
5239 def test_delete_created_items_already_deleted(
5240 self,
5241 mock_delete_floating_ip_by_id,
5242 mock_delete_volumes_by_id_wth_cinder,
5243 mock_get_item_name_id,
5244 ):
5245 """All created items are alerady deleted."""
5246 created_items = {
5247 f"floating_ip:{floating_network_vim_id}": None,
5248 f"volume:{volume_id}": None,
5249 f"port:{port_id}": None,
5250 }
5251 volumes_to_hold = []
5252 keep_waiting = False
5253 result = self.vimconn._delete_created_items(
5254 created_items, volumes_to_hold, keep_waiting
5255 )
5256 self.assertEqual(result, False)
5257 mock_get_item_name_id.assert_not_called()
5258 mock_delete_volumes_by_id_wth_cinder.assert_not_called()
5259 mock_delete_floating_ip_by_id.assert_not_called()
5260 self.vimconn.logger.error.assert_not_called()
5261
5262 @patch("time.sleep")
5263 @patch.object(vimconnector, "_format_exception")
5264 @patch.object(vimconnector, "_reload_connection")
5265 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5266 @patch.object(vimconnector, "_delete_created_items")
5267 def test_delete_vminstance_successfully(
5268 self,
5269 mock_delete_created_items,
5270 mock_delete_vm_ports_attached_to_network,
5271 mock_reload_connection,
5272 mock_format_exception,
5273 mock_sleep,
5274 ):
5275 vm_id = f"{virtual_mac_id}"
5276 created_items = deepcopy(created_items_all_true)
5277 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5278 mock_delete_created_items.return_value = False
5279 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5280 mock_reload_connection.assert_called_once()
5281 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
5282 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
5283 mock_delete_created_items.assert_called_once_with(
5284 created_items, volumes_to_hold, False
5285 )
5286 mock_sleep.assert_not_called()
5287 mock_format_exception.assert_not_called()
5288
5289 @patch("time.sleep")
5290 @patch.object(vimconnector, "_format_exception")
5291 @patch.object(vimconnector, "_reload_connection")
5292 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5293 @patch.object(vimconnector, "_delete_created_items")
5294 def test_delete_vminstance_delete_created_items_raises(
5295 self,
5296 mock_delete_created_items,
5297 mock_delete_vm_ports_attached_to_network,
5298 mock_reload_connection,
5299 mock_format_exception,
5300 mock_sleep,
5301 ):
5302 """Delete creted items raises exception."""
5303 vm_id = f"{virtual_mac_id}"
5304 created_items = deepcopy(created_items_all_true)
5305 mock_sleep = MagicMock()
5306 volumes_to_hold = []
5307 err = ConnectionError("ClientException occured.")
5308 mock_delete_created_items.side_effect = err
5309 with self.assertRaises(ConnectionError) as err:
5310 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5311 self.assertEqual(str(err), "ClientException occured.")
5312 mock_reload_connection.assert_called_once()
5313 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
5314 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
5315 mock_delete_created_items.assert_called_once()
5316 mock_sleep.assert_not_called()
5317
5318 @patch("time.sleep")
5319 @patch.object(vimconnector, "_format_exception")
5320 @patch.object(vimconnector, "_reload_connection")
5321 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5322 @patch.object(vimconnector, "_delete_created_items")
5323 def test_delete_vminstance_delete_vm_ports_raises(
5324 self,
5325 mock_delete_created_items,
5326 mock_delete_vm_ports_attached_to_network,
5327 mock_reload_connection,
5328 mock_format_exception,
5329 mock_sleep,
5330 ):
5331 """Delete vm ports raises exception."""
5332 vm_id = f"{virtual_mac_id}"
5333 created_items = deepcopy(created_items_all_true)
5334 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5335 err = ConnectionError("ClientException occured.")
5336 mock_delete_vm_ports_attached_to_network.side_effect = err
5337 mock_delete_created_items.side_effect = err
5338 with self.assertRaises(ConnectionError) as err:
5339 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5340 self.assertEqual(str(err), "ClientException occured.")
5341 mock_reload_connection.assert_called_once()
5342 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
5343 self.vimconn.nova.servers.delete.assert_not_called()
5344 mock_delete_created_items.assert_not_called()
5345 mock_sleep.assert_not_called()
5346
5347 @patch("time.sleep")
5348 @patch.object(vimconnector, "_format_exception")
5349 @patch.object(vimconnector, "_reload_connection")
5350 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5351 @patch.object(vimconnector, "_delete_created_items")
5352 def test_delete_vminstance_nova_server_delete_raises(
5353 self,
5354 mock_delete_created_items,
5355 mock_delete_vm_ports_attached_to_network,
5356 mock_reload_connection,
5357 mock_format_exception,
5358 mock_sleep,
5359 ):
5360 """Nova server delete raises exception."""
5361 vm_id = f"{virtual_mac_id}"
5362 created_items = deepcopy(created_items_all_true)
5363 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5364 err = VimConnConnectionException("ClientException occured.")
5365 self.vimconn.nova.servers.delete.side_effect = err
5366 mock_delete_created_items.side_effect = err
5367 with self.assertRaises(VimConnConnectionException) as err:
5368 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5369 self.assertEqual(str(err), "ClientException occured.")
5370 mock_reload_connection.assert_called_once()
5371 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
5372 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
5373 mock_delete_created_items.assert_not_called()
5374 mock_sleep.assert_not_called()
5375
5376 @patch("time.sleep")
5377 @patch.object(vimconnector, "_format_exception")
5378 @patch.object(vimconnector, "_reload_connection")
5379 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5380 @patch.object(vimconnector, "_delete_created_items")
5381 def test_delete_vminstance_reload_connection_raises(
5382 self,
5383 mock_delete_created_items,
5384 mock_delete_vm_ports_attached_to_network,
5385 mock_reload_connection,
5386 mock_format_exception,
5387 mock_sleep,
5388 ):
5389 """Reload connection raises exception."""
5390 vm_id = f"{virtual_mac_id}"
5391 created_items = deepcopy(created_items_all_true)
5392 mock_sleep = MagicMock()
5393 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5394 err = ConnectionError("ClientException occured.")
5395 mock_delete_created_items.return_value = False
5396 mock_reload_connection.side_effect = err
5397 with self.assertRaises(ConnectionError) as err:
5398 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5399 self.assertEqual(str(err), "ClientException occured.")
5400 mock_reload_connection.assert_called_once()
5401 mock_delete_vm_ports_attached_to_network.assert_not_called()
5402 self.vimconn.nova.servers.delete.assert_not_called()
5403 mock_delete_created_items.assert_not_called()
5404 mock_sleep.assert_not_called()
5405
5406 @patch("time.sleep")
5407 @patch.object(vimconnector, "_format_exception")
5408 @patch.object(vimconnector, "_reload_connection")
5409 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5410 @patch.object(vimconnector, "_delete_created_items")
5411 def test_delete_vminstance_created_item_vol_to_hold_are_none(
5412 self,
5413 mock_delete_created_items,
5414 mock_delete_vm_ports_attached_to_network,
5415 mock_reload_connection,
5416 mock_format_exception,
5417 mock_sleep,
5418 ):
5419 """created_items and volumes_to_hold are None."""
5420 vm_id = f"{virtual_mac_id}"
5421 created_items = None
5422 volumes_to_hold = None
5423 mock_delete_created_items.return_value = False
5424 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5425 mock_reload_connection.assert_called_once()
5426 mock_delete_vm_ports_attached_to_network.assert_not_called()
5427 self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
5428 mock_delete_created_items.assert_called_once_with({}, [], False)
5429 mock_sleep.assert_not_called()
5430 mock_format_exception.assert_not_called()
5431
5432 @patch("time.sleep")
5433 @patch.object(vimconnector, "_format_exception")
5434 @patch.object(vimconnector, "_reload_connection")
5435 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5436 @patch.object(vimconnector, "_delete_created_items")
5437 def test_delete_vminstance_vm_id_is_none(
5438 self,
5439 mock_delete_created_items,
5440 mock_delete_vm_ports_attached_to_network,
5441 mock_reload_connection,
5442 mock_format_exception,
5443 mock_sleep,
5444 ):
5445 """vm_id is None."""
5446 vm_id = None
5447 created_items = deepcopy(created_items_all_true)
5448 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5449 mock_delete_created_items.side_effect = [True, True, False]
5450 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5451 mock_reload_connection.assert_called_once()
5452 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
5453 self.vimconn.nova.servers.delete.assert_not_called()
5454 self.assertEqual(mock_delete_created_items.call_count, 3)
5455 self.assertEqual(mock_sleep.call_count, 2)
5456 mock_format_exception.assert_not_called()
5457
5458 @patch("time.sleep")
5459 @patch.object(vimconnector, "_format_exception")
5460 @patch.object(vimconnector, "_reload_connection")
5461 @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
5462 @patch.object(vimconnector, "_delete_created_items")
5463 def test_delete_vminstance_delete_created_items_return_true(
5464 self,
5465 mock_delete_created_items,
5466 mock_delete_vm_ports_attached_to_network,
5467 mock_reload_connection,
5468 mock_format_exception,
5469 mock_sleep,
5470 ):
5471 """Delete created items always return True."""
5472 vm_id = None
5473 created_items = deepcopy(created_items_all_true)
5474 volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
5475 mock_delete_created_items.side_effect = [True] * 1800
5476 self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
5477 mock_reload_connection.assert_called_once()
5478 mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
5479 self.vimconn.nova.servers.delete.assert_not_called()
5480 self.assertEqual(mock_delete_created_items.call_count, 1800)
5481 self.assertEqual(mock_sleep.call_count, 1800)
5482 mock_format_exception.assert_not_called()
5483
5484
5485 if __name__ == "__main__":
5486 unittest.main()