Feature 11003: AZ for Cinder
[osm/RO.git] / RO-VIM-openstack / osm_rovim_openstack / tests / test_vimconn_openstack.py
index d4359cd..44b63d2 100644 (file)
@@ -27,15 +27,19 @@ from copy import deepcopy
 import logging
 import unittest
 
+import cinderclient.exceptions as cExceptions
 from mock import MagicMock, patch
+from neutronclient.common import exceptions as neExceptions
 from novaclient import exceptions as nvExceptions
 from novaclient.exceptions import ClientException, Conflict
 from osm_ro_plugin.vimconn import (
     VimConnConnectionException,
     VimConnException,
     VimConnNotFoundException,
+    VimConnUnexpectedResponse,
 )
 from osm_rovim_openstack.vimconn_openstack import vimconnector
+from requests.exceptions import ConnectionError
 
 __author__ = "Igor D.C."
 __date__ = "$23-aug-2017 23:59:59$"
@@ -68,6 +72,7 @@ ip_addr1 = "20.3.4.5"
 volume_id = "ac408b73-b9cc-4a6a-a270-82cc4811bd4a"
 volume_id2 = "o4e0e83-b9uu-4akk-a234-89cc4811bd4a"
 volume_id3 = "44e0e83-t9uu-4akk-a234-p9cc4811bd4a"
+volume_id4 = "91bf5674-5b85-41d1-aa3b-4848e2691088"
 virtual_mac_id = "64e0e83-t9uu-4akk-a234-p9cc4811bd4a"
 created_items_all_true = {
     f"floating_ip:{floating_network_vim_id}": True,
@@ -108,12 +113,20 @@ def check_if_assert_not_called(mocks: list):
         mocking.assert_not_called()
 
 
-class Status:
-    def __init__(self, s):
+class Volume:
+    def __init__(self, s, type="__DEFAULT__", name="", id=""):
         self.status = s
+        self.volume_type = type
+        self.name = name
+        self.id = id
 
-    def __str__(self):
-        return self.status
+
+class Server:
+    def __init__(self, name="", status="", flavor="", id=""):
+        self.id = id
+        self.name = name
+        self.status = status
+        self.flavor = flavor
 
 
 class CopyingMock(MagicMock):
@@ -359,7 +372,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
         self.assertDictEqual(port_dict, result_dict)
 
-    def test_prepare_port_dict_mac_ip_addr_no_mac_and_ip(self):
+    def test_prepare_port_dict_mac_ip_addr_empty_net(self):
         """mac address and ip address does not exist."""
         net = {}
         port_dict = {}
@@ -367,6 +380,67 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
         self.assertDictEqual(port_dict, result_dict)
 
+    def test_prepare_port_dict_mac_ip_addr_dual(self):
+        """mac address, ipv4 and ipv6 addresses exist."""
+        net = {
+            "mac_address": mac_address,
+            "ip_address": ["10.0.1.5", "2345:0425:2CA1:0000:0000:0567:5673:23b5"],
+        }
+        port_dict = {}
+        result_dict = {
+            "mac_address": mac_address,
+            "fixed_ips": [
+                {"ip_address": "10.0.1.5"},
+                {"ip_address": "2345:0425:2CA1:0000:0000:0567:5673:23b5"},
+            ],
+        }
+        self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
+        self.assertDictEqual(port_dict, result_dict)
+
+    def test_prepare_port_dict_mac_ip_addr_dual_ip_addr_is_not_list(self):
+        """mac address, ipv4 and ipv6 addresses exist."""
+        net = {
+            "mac_address": mac_address,
+            "ip_address": "10.0.1.5",
+        }
+        port_dict = {}
+        result_dict = {
+            "mac_address": mac_address,
+            "fixed_ips": [
+                {"ip_address": "10.0.1.5"},
+            ],
+        }
+        self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
+        self.assertDictEqual(port_dict, result_dict)
+
+    def test_prepare_port_dict_mac_ip_addr_dual_net_without_ip_addr(self):
+        """mac address, ipv4 and ipv6 addresses exist."""
+        net = {
+            "mac_address": mac_address,
+            "ip_address": [],
+        }
+        port_dict = {}
+        result_dict = {
+            "mac_address": mac_address,
+        }
+        self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
+        self.assertDictEqual(port_dict, result_dict)
+
+    def test_prepare_port_dict_mac_ip_addr_dual_net_without_mac_addr(self):
+        """mac address, ipv4 and ipv6 addresses exist."""
+        net = {
+            "ip_address": ["10.0.1.5", "2345:0425:2CA1:0000:0000:0567:5673:23b5"],
+        }
+        port_dict = {}
+        result_dict = {
+            "fixed_ips": [
+                {"ip_address": "10.0.1.5"},
+                {"ip_address": "2345:0425:2CA1:0000:0000:0567:5673:23b5"},
+            ],
+        }
+        self.vimconn._prepare_port_dict_mac_ip_addr(net, port_dict)
+        self.assertDictEqual(port_dict, result_dict)
+
     def test_create_new_port(self):
         """new port has id and mac address."""
         new_port = {
@@ -379,7 +453,7 @@ class TestNewVmInstance(unittest.TestCase):
         net, port_dict, created_items = {}, {}, {}
         expected_result = new_port
         expected_net = {
-            "mac_adress": mac_address,
+            "mac_address": mac_address,
             "vim_id": port_id,
         }
         expected_created_items = {f"port:{port_id}": True}
@@ -1228,7 +1302,7 @@ class TestNewVmInstance(unittest.TestCase):
 
     def test_prepare_persistent_root_volumes_vim_using_volume_id(self):
         """Existing persistent root volume with vim_volume_id."""
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("a")
         disk = {"vim_volume_id": volume_id}
         block_device_mapping = {}
@@ -1239,7 +1313,7 @@ class TestNewVmInstance(unittest.TestCase):
         expected_existing_vim_volumes = [{"id": volume_id}]
         boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
             name,
-            vm_av_zone,
+            storage_av_zone,
             disk,
             base_disk_index,
             block_device_mapping,
@@ -1251,12 +1325,50 @@ class TestNewVmInstance(unittest.TestCase):
         self.assertEqual(existing_vim_volumes, expected_existing_vim_volumes)
         self.vimconn.cinder.volumes.create.assert_not_called()
 
+    @patch.object(vimconnector, "update_block_device_mapping")
+    def test__prepare_shared_volumes_vim_using_volume_id(
+        self, mock_update_block_device_mapping
+    ):
+        """Existing persistent non root volume with vim_volume_id.
+        class Volume:
+            def __init__(self, s, type="__DEFAULT__", name="", id=""):
+                self.status = s
+                self.volume_type = type
+                self.name = name
+                self.id = id
+        volumes = {"shared-volume": volume_id4}
+
+        The device mappeing BEFORE is: {}
+        The device mappeing AFTER is: {'vdb': '8ca50cc6-a779-4513-a1f3-900b8b3987d2'}
+        """
+        base_disk_index = ord("b")
+        disk = {"name": "shared-volume"}
+        block_device_mapping = {}
+        existing_vim_volumes = []
+        created_items = {}
+        expected_block_device_mapping = {}
+        self.vimconn.cinder.volumes.list.return_value = [
+            Volume("available", "multiattach", "shared-volume", volume_id4)
+        ]
+        self.vimconn.cinder.volumes.get.return_value.id = volume_id4
+        self.vimconn.cinder.volumes.get.return_value.status = "available"
+        self.vimconn._prepare_shared_volumes(
+            name,
+            disk,
+            base_disk_index,
+            block_device_mapping,
+            existing_vim_volumes,
+            created_items,
+        )
+        self.vimconn.cinder.volumes.get.assert_called_with(volume_id4)
+        self.assertDictEqual(block_device_mapping, expected_block_device_mapping)
+
     @patch.object(vimconnector, "update_block_device_mapping")
     def test_prepare_persistent_non_root_volumes_vim_using_volume_id(
         self, mock_update_block_device_mapping
     ):
         """Existing persistent non root volume with vim_volume_id."""
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("b")
         disk = {"vim_volume_id": volume_id}
         block_device_mapping = {}
@@ -1267,7 +1379,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn._prepare_non_root_persistent_volumes(
             name,
             disk,
-            vm_av_zone,
+            storage_av_zone,
             block_device_mapping,
             base_disk_index,
             existing_vim_volumes,
@@ -1283,7 +1395,7 @@ class TestNewVmInstance(unittest.TestCase):
         self, mock_update_block_device_mapping
     ):
         """Existing persistent root volume with vim_id."""
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("a")
         disk = {"vim_id": volume_id}
         block_device_mapping = {}
@@ -1294,7 +1406,7 @@ class TestNewVmInstance(unittest.TestCase):
         expected_existing_vim_volumes = [{"id": volume_id}]
         boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
             name,
-            vm_av_zone,
+            storage_av_zone,
             disk,
             base_disk_index,
             block_device_mapping,
@@ -1312,7 +1424,7 @@ class TestNewVmInstance(unittest.TestCase):
         self, mock_update_block_device_mapping
     ):
         """Existing persistent root volume with vim_id."""
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("b")
         disk = {"vim_id": volume_id}
         block_device_mapping = {}
@@ -1324,7 +1436,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn._prepare_non_root_persistent_volumes(
             name,
             disk,
-            vm_av_zone,
+            storage_av_zone,
             block_device_mapping,
             base_disk_index,
             existing_vim_volumes,
@@ -1342,7 +1454,7 @@ class TestNewVmInstance(unittest.TestCase):
     ):
         """Create persistent root volume."""
         self.vimconn.cinder.volumes.create.return_value.id = volume_id2
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("a")
         disk = {"size": 10, "image_id": image_id}
         block_device_mapping = {}
@@ -1351,7 +1463,7 @@ class TestNewVmInstance(unittest.TestCase):
         expected_boot_vol_id = volume_id2
         boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
             name,
-            vm_av_zone,
+            storage_av_zone,
             disk,
             base_disk_index,
             block_device_mapping,
@@ -1387,7 +1499,7 @@ class TestNewVmInstance(unittest.TestCase):
     ):
         """Create persistent root volume, disk has keep parameter."""
         self.vimconn.cinder.volumes.create.return_value.id = volume_id2
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("a")
         disk = {"size": 10, "image_id": image_id, "keep": True}
         block_device_mapping = {}
@@ -1397,7 +1509,7 @@ class TestNewVmInstance(unittest.TestCase):
         expected_existing_vim_volumes = []
         boot_volume_id = self.vimconn._prepare_persistent_root_volumes(
             name,
-            vm_av_zone,
+            storage_av_zone,
             disk,
             base_disk_index,
             block_device_mapping,
@@ -1435,7 +1547,7 @@ class TestNewVmInstance(unittest.TestCase):
         """Create persistent non-root volume."""
         self.vimconn.cinder = CopyingMock()
         self.vimconn.cinder.volumes.create.return_value.id = volume_id2
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("a")
         disk = {"size": 10}
         block_device_mapping = {}
@@ -1445,7 +1557,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn._prepare_non_root_persistent_volumes(
             name,
             disk,
-            vm_av_zone,
+            storage_av_zone,
             block_device_mapping,
             base_disk_index,
             existing_vim_volumes,
@@ -1479,7 +1591,7 @@ class TestNewVmInstance(unittest.TestCase):
         """Create persistent non-root volume."""
         self.vimconn.cinder = CopyingMock()
         self.vimconn.cinder.volumes.create.return_value.id = volume_id2
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("a")
         disk = {"size": 10, "keep": True}
         block_device_mapping = {}
@@ -1489,7 +1601,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn._prepare_non_root_persistent_volumes(
             name,
             disk,
-            vm_av_zone,
+            storage_av_zone,
             block_device_mapping,
             base_disk_index,
             existing_vim_volumes,
@@ -1516,13 +1628,35 @@ class TestNewVmInstance(unittest.TestCase):
             _call_mock_update_block_device_mapping[0].kwargs["created_items"], {}
         )
 
+    @patch.object(vimconnector, "update_block_device_mapping")
+    def test_new_shared_volumes(self, mock_update_block_device_mapping):
+        """Create shared volume."""
+
+        class MyVolume:
+            name = "my-shared-volume"
+            id = volume_id4
+            availability_zone = ["nova"]
+
+        self.vimconn.storage_availability_zone = ["nova"]
+        self.vimconn.cinder.volumes.create.return_value = MyVolume()
+        shared_volume_data = {"size": 10, "name": "my-shared-volume"}
+        result = self.vimconn.new_shared_volumes(shared_volume_data)
+        self.vimconn.cinder.volumes.create.assert_called_once_with(
+            size=10,
+            name="my-shared-volume",
+            volume_type="multiattach",
+            availability_zone=["nova"],
+        )
+        self.assertEqual(result[0], "my-shared-volume")
+        self.assertEqual(result[1], volume_id4)
+
     @patch.object(vimconnector, "update_block_device_mapping")
     def test_prepare_persistent_root_volumes_create_raise_exception(
         self, mock_update_block_device_mapping
     ):
         """Create persistent root volume raise exception."""
         self.vimconn.cinder.volumes.create.side_effect = Exception
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("a")
         disk = {"size": 10, "image_id": image_id}
         block_device_mapping = {}
@@ -1532,7 +1666,7 @@ class TestNewVmInstance(unittest.TestCase):
         with self.assertRaises(Exception):
             result = self.vimconn._prepare_persistent_root_volumes(
                 name,
-                vm_av_zone,
+                storage_av_zone,
                 disk,
                 base_disk_index,
                 block_device_mapping,
@@ -1559,7 +1693,7 @@ class TestNewVmInstance(unittest.TestCase):
     ):
         """Create persistent non-root volume raise exception."""
         self.vimconn.cinder.volumes.create.side_effect = Exception
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         base_disk_index = ord("b")
         disk = {"size": 10}
         block_device_mapping = {}
@@ -1570,7 +1704,7 @@ class TestNewVmInstance(unittest.TestCase):
             self.vimconn._prepare_non_root_persistent_volumes(
                 name,
                 disk,
-                vm_av_zone,
+                storage_av_zone,
                 block_device_mapping,
                 base_disk_index,
                 existing_vim_volumes,
@@ -1628,9 +1762,9 @@ class TestNewVmInstance(unittest.TestCase):
             f"volume:{volume_id3}": True,
         }
         self.vimconn.cinder.volumes.get.side_effect = [
-            Status("processing"),
-            Status("available"),
-            Status("available"),
+            Volume("processing"),
+            Volume("available"),
+            Volume("available"),
         ]
 
         result = self.vimconn._wait_for_created_volumes_availability(
@@ -1655,9 +1789,9 @@ class TestNewVmInstance(unittest.TestCase):
             {"id": "44e0e83-b9uu-4akk-t234-p9cc4811bd4a"},
         ]
         self.vimconn.cinder.volumes.get.side_effect = [
-            Status("processing"),
-            Status("available"),
-            Status("available"),
+            Volume("processing"),
+            Volume("available", "multiattach"),
+            Volume("available"),
         ]
 
         result = self.vimconn._wait_for_existing_volumes_availability(
@@ -1681,8 +1815,8 @@ class TestNewVmInstance(unittest.TestCase):
         elapsed_time = 1805
         created_items = {f"volume:{volume_id2}": True}
         self.vimconn.cinder.volumes.get.side_effect = [
-            Status("processing"),
-            Status("processing"),
+            Volume("processing"),
+            Volume("processing"),
         ]
         with patch("time.sleep", mock_sleep):
             result = self.vimconn._wait_for_created_volumes_availability(
@@ -1700,8 +1834,8 @@ class TestNewVmInstance(unittest.TestCase):
         elapsed_time = 1805
         existing_vim_volumes = [{"id": volume_id2}]
         self.vimconn.cinder.volumes.get.side_effect = [
-            Status("processing"),
-            Status("processing"),
+            Volume("processing"),
+            Volume("processing"),
         ]
 
         result = self.vimconn._wait_for_existing_volumes_availability(
@@ -1792,7 +1926,7 @@ class TestNewVmInstance(unittest.TestCase):
         existing_vim_volumes = []
         created_items = {}
         block_device_mapping = {}
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
 
         mock_root_volumes.return_value = root_vol_id
         mock_created_vol_availability.return_value = 10
@@ -1802,7 +1936,7 @@ class TestNewVmInstance(unittest.TestCase):
             name,
             existing_vim_volumes,
             created_items,
-            vm_av_zone,
+            storage_av_zone,
             block_device_mapping,
             disk_list2,
         )
@@ -1815,7 +1949,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.assertEqual(mock_non_root_volumes.call_count, 1)
         mock_root_volumes.assert_called_once_with(
             name="basicvm",
-            vm_av_zone=["nova"],
+            storage_av_zone=["nova"],
             disk={"size": 10, "image_id": image_id},
             base_disk_index=97,
             block_device_mapping={},
@@ -1825,7 +1959,7 @@ class TestNewVmInstance(unittest.TestCase):
         mock_non_root_volumes.assert_called_once_with(
             name="basicvm",
             disk={"size": 20},
-            vm_av_zone=["nova"],
+            storage_av_zone=["nova"],
             base_disk_index=98,
             block_device_mapping={},
             existing_vim_volumes=[],
@@ -1846,7 +1980,7 @@ class TestNewVmInstance(unittest.TestCase):
         """Timeout exceeded while waiting for disks."""
         existing_vim_volumes = []
         created_items = {}
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         block_device_mapping = {}
 
         mock_root_volumes.return_value = root_vol_id
@@ -1858,7 +1992,7 @@ class TestNewVmInstance(unittest.TestCase):
                 name,
                 existing_vim_volumes,
                 created_items,
-                vm_av_zone,
+                storage_av_zone,
                 block_device_mapping,
                 disk_list2,
             )
@@ -1874,7 +2008,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.assertEqual(mock_non_root_volumes.call_count, 1)
         mock_root_volumes.assert_called_once_with(
             name="basicvm",
-            vm_av_zone=["nova"],
+            storage_av_zone=["nova"],
             disk={"size": 10, "image_id": image_id},
             base_disk_index=97,
             block_device_mapping={},
@@ -1884,7 +2018,7 @@ class TestNewVmInstance(unittest.TestCase):
         mock_non_root_volumes.assert_called_once_with(
             name="basicvm",
             disk={"size": 20},
-            vm_av_zone=["nova"],
+            storage_av_zone=["nova"],
             base_disk_index=98,
             block_device_mapping={},
             existing_vim_volumes=[],
@@ -1906,7 +2040,7 @@ class TestNewVmInstance(unittest.TestCase):
         existing_vim_volumes = []
         created_items = {}
         block_device_mapping = {}
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         mock_created_vol_availability.return_value = 2
         mock_existing_vol_availability.return_value = 3
 
@@ -1914,7 +2048,7 @@ class TestNewVmInstance(unittest.TestCase):
             name,
             existing_vim_volumes,
             created_items,
-            vm_av_zone,
+            storage_av_zone,
             block_device_mapping,
             disk_list,
         )
@@ -1938,7 +2072,7 @@ class TestNewVmInstance(unittest.TestCase):
         """Persistent root volumes preparation raises error."""
         existing_vim_volumes = []
         created_items = {}
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         block_device_mapping = {}
 
         mock_root_volumes.side_effect = Exception()
@@ -1950,7 +2084,7 @@ class TestNewVmInstance(unittest.TestCase):
                 name,
                 existing_vim_volumes,
                 created_items,
-                vm_av_zone,
+                storage_av_zone,
                 block_device_mapping,
                 disk_list2,
             )
@@ -1959,7 +2093,7 @@ class TestNewVmInstance(unittest.TestCase):
         mock_existing_vol_availability.assert_not_called()
         mock_root_volumes.assert_called_once_with(
             name="basicvm",
-            vm_av_zone=["nova"],
+            storage_av_zone=["nova"],
             disk={"size": 10, "image_id": image_id},
             base_disk_index=97,
             block_device_mapping={},
@@ -1982,7 +2116,7 @@ class TestNewVmInstance(unittest.TestCase):
         """Non-root volumes preparation raises error."""
         existing_vim_volumes = []
         created_items = {}
-        vm_av_zone = ["nova"]
+        storage_av_zone = ["nova"]
         block_device_mapping = {}
 
         mock_root_volumes.return_value = root_vol_id
@@ -1993,7 +2127,7 @@ class TestNewVmInstance(unittest.TestCase):
                 name,
                 existing_vim_volumes,
                 created_items,
-                vm_av_zone,
+                storage_av_zone,
                 block_device_mapping,
                 disk_list2,
             )
@@ -2004,7 +2138,7 @@ class TestNewVmInstance(unittest.TestCase):
         self.assertEqual(mock_non_root_volumes.call_count, 1)
         mock_root_volumes.assert_called_once_with(
             name="basicvm",
-            vm_av_zone=["nova"],
+            storage_av_zone=["nova"],
             disk={"size": 10, "image_id": image_id},
             base_disk_index=97,
             block_device_mapping={},
@@ -2014,7 +2148,7 @@ class TestNewVmInstance(unittest.TestCase):
         mock_non_root_volumes.assert_called_once_with(
             name="basicvm",
             disk={"size": 20},
-            vm_av_zone=["nova"],
+            storage_av_zone=["nova"],
             base_disk_index=98,
             block_device_mapping={},
             existing_vim_volumes=[],
@@ -3171,7 +3305,7 @@ class TestNewVmInstance(unittest.TestCase):
             name=name,
             existing_vim_volumes=[],
             created_items={},
-            vm_av_zone="nova",
+            storage_av_zone="nova",
             block_device_mapping={},
             disk_list=disk_list2,
         )
@@ -3348,7 +3482,7 @@ class TestNewVmInstance(unittest.TestCase):
             name=name,
             existing_vim_volumes=[],
             created_items={},
-            vm_av_zone="nova",
+            storage_av_zone="nova",
             block_device_mapping={},
             disk_list=disk_list2,
         )
@@ -3446,7 +3580,7 @@ class TestNewVmInstance(unittest.TestCase):
             name=name,
             existing_vim_volumes=[],
             created_items={},
-            vm_av_zone="nova",
+            storage_av_zone="nova",
             block_device_mapping={},
             disk_list=disk_list2,
         )
@@ -3545,7 +3679,7 @@ class TestNewVmInstance(unittest.TestCase):
             name=name,
             existing_vim_volumes=[],
             created_items={},
-            vm_av_zone="nova",
+            storage_av_zone="nova",
             block_device_mapping={},
             disk_list=disk_list2,
         )
@@ -3770,7 +3904,9 @@ class TestNewVmInstance(unittest.TestCase):
             },
         )
 
-    def test_delete_floating_ip_by_id_floating_ip_raises_nvexception(self):
+    def test_delete_floating_ip_by_id__delete_floating_ip_raises_client_exception__operation_is_successful(
+        self,
+    ):
         """netron delete floating ip raises nvExceptions.ClientException."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
@@ -3794,7 +3930,36 @@ class TestNewVmInstance(unittest.TestCase):
             "Error deleting floating ip: ClientException: Unknown Error (HTTP Client exception occurred.)"
         )
 
-    def test_delete_floating_ip_by_id_floating_ip_raises_vimconnexception(self):
+    def test_delete_floating_ip_by_id__delete_floating_ip_raises_connection_error__operation_fails(
+        self,
+    ):
+        """netron delete floating ip raises nvExceptions.ClientException."""
+        created_items = {
+            f"floating_ip:{floating_network_vim_id}": True,
+            f"port:{port_id}": True,
+        }
+        k_id = floating_network_vim_id
+        k = f"floating_ip:{floating_network_vim_id}"
+        self.vimconn.neutron.delete_floatingip.side_effect = ConnectionError(
+            "Connection exception occurred."
+        )
+        with self.assertRaises(VimConnConnectionException):
+            self.vimconn._delete_floating_ip_by_id(k, k_id, created_items)
+        self.vimconn.neutron.delete_floatingip.assert_called_once_with(k_id)
+        self.assertEqual(
+            created_items,
+            {
+                f"floating_ip:{floating_network_vim_id}": True,
+                f"port:{port_id}": True,
+            },
+        )
+        self.vimconn.logger.error.assert_called_once_with(
+            "Error deleting floating ip: ConnectionError: Connection exception occurred."
+        )
+
+    def test_delete_floating_ip_by_id_floating_ip_raises_vimconn_not_found_exception__operation_is_successful(
+        self,
+    ):
         """netron delete floating ip raises VimConnNotFoundException."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
@@ -3889,6 +4054,15 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn.logger.error.assert_not_called()
         self.assertEqual(created_items, expected_created_items)
 
+    def test_delete_shared_volumes(self):
+        """cinder delete shared volumes"""
+        shared_volume_vim_id = volume_id4
+        self.vimconn.cinder.volumes.get.return_value.status = "available"
+        self.vimconn.delete_shared_volumes(shared_volume_vim_id)
+        self.vimconn.cinder.volumes.get.assert_called_once_with(shared_volume_vim_id)
+        self.vimconn.cinder.volumes.delete.assert_called_once_with(shared_volume_vim_id)
+        self.vimconn.logger.error.assert_not_called()
+
     def test_delete_volumes_by_id_with_cinder_get_volume_raise_exception(self):
         """cinder get volume raises exception."""
         created_items = {
@@ -3920,7 +4094,9 @@ class TestNewVmInstance(unittest.TestCase):
         )
         self.assertEqual(created_items, expected_created_items)
 
-    def test_delete_volumes_by_id_with_cinder_delete_volume_raise_exception(self):
+    def test_delete_volumes_by_id_with_cinder__delete_volume_raise_client_exception__exception_is_not_raised(
+        self,
+    ):
         """cinder delete volume raises exception."""
         created_items = {
             f"floating_ip:{floating_network_vim_id}": True,
@@ -3938,8 +4114,8 @@ class TestNewVmInstance(unittest.TestCase):
         k = f"volume:{volume_id}"
         k_id = volume_id
         self.vimconn.cinder.volumes.get.return_value.status = "available"
-        self.vimconn.cinder.volumes.delete.side_effect = nvExceptions.ClientException(
-            "Connection aborted."
+        self.vimconn.cinder.volumes.delete.side_effect = cExceptions.ClientException(
+            403, "Connection aborted."
         )
         result = self.vimconn._delete_volumes_by_id_wth_cinder(
             k, k_id, volumes_to_hold, created_items
@@ -3948,7 +4124,42 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
         self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
         self.vimconn.logger.error.assert_called_once_with(
-            "Error deleting volume: ClientException: Unknown Error (HTTP Connection aborted.)"
+            "Error deleting volume: ClientException: Connection aborted. (HTTP 403)"
+        )
+        self.assertEqual(created_items, expected_created_items)
+
+    def test_delete_volumes_by_id_with_cinder__delete_volume_raise_connection_exception__exception_is_raised(
+        self,
+    ):
+        """cinder delete volume raises exception."""
+        created_items = {
+            f"floating_ip:{floating_network_vim_id}": True,
+            f"volume:{volume_id2}": True,
+            f"volume:{volume_id}": True,
+            f"port:{port_id}": None,
+        }
+        expected_created_items = {
+            f"floating_ip:{floating_network_vim_id}": True,
+            f"volume:{volume_id2}": True,
+            f"volume:{volume_id}": True,
+            f"port:{port_id}": None,
+        }
+        volumes_to_hold = []
+        k = f"volume:{volume_id}"
+        k_id = volume_id
+        self.vimconn.cinder.volumes.get.return_value.status = "available"
+        self.vimconn.cinder.volumes.delete.side_effect = cExceptions.ConnectionError(
+            "Connection failed."
+        )
+        with self.assertRaises(VimConnConnectionException):
+            result = self.vimconn._delete_volumes_by_id_wth_cinder(
+                k, k_id, volumes_to_hold, created_items
+            )
+            self.assertEqual(result, None)
+        self.vimconn.cinder.volumes.get.assert_called_once_with(k_id)
+        self.vimconn.cinder.volumes.delete.assert_called_once_with(k_id)
+        self.vimconn.logger.error.assert_called_once_with(
+            "Error deleting volume: ConnectionError: Connection failed."
         )
         self.assertEqual(created_items, expected_created_items)
 
@@ -3972,7 +4183,7 @@ class TestNewVmInstance(unittest.TestCase):
         result = self.vimconn._delete_volumes_by_id_wth_cinder(
             k, k_id, volumes_to_hold, created_items
         )
-        self.assertEqual(result, None)
+        self.assertEqual(result, False)
         self.vimconn.cinder.volumes.get.assert_not_called()
         self.vimconn.cinder.volumes.delete.assert_not_called()
         self.vimconn.logger.error.assert_not_called()
@@ -4008,51 +4219,17 @@ class TestNewVmInstance(unittest.TestCase):
     def test_delete_ports_by_id_by_neutron(self):
         """neutron delete ports."""
         k_id = port_id
-        self.vimconn.neutron.list_ports.return_value = {
-            "ports": [{"id": port_id}, {"id": port2_id}]
-        }
-
         self.vimconn._delete_ports_by_id_wth_neutron(k_id)
-        self.vimconn.neutron.list_ports.assert_called_once()
         self.vimconn.neutron.delete_port.assert_called_once_with(k_id)
         self.vimconn.logger.error.assert_not_called()
 
-    def test_delete_ports_by_id_by_neutron_id_not_in_port_list(self):
-        """port id not in the port list."""
-        k_id = volume_id
-        self.vimconn.neutron.list_ports.return_value = {
-            "ports": [{"id": port_id}, {"id": port2_id}]
-        }
-
-        self.vimconn._delete_ports_by_id_wth_neutron(k_id)
-        self.vimconn.neutron.list_ports.assert_called_once()
-        self.vimconn.neutron.delete_port.assert_not_called()
-        self.vimconn.logger.error.assert_not_called()
-
-    def test_delete_ports_by_id_by_neutron_list_port_raise_exception(self):
-        """neutron list port raises exception."""
-        k_id = port_id
-        self.vimconn.neutron.list_ports.side_effect = nvExceptions.ClientException(
-            "Connection aborted."
-        )
-        self.vimconn._delete_ports_by_id_wth_neutron(k_id)
-        self.vimconn.neutron.list_ports.assert_called_once()
-        self.vimconn.neutron.delete_port.assert_not_called()
-        self.vimconn.logger.error.assert_called_once_with(
-            "Error deleting port: ClientException: Unknown Error (HTTP Connection aborted.)"
-        )
-
     def test_delete_ports_by_id_by_neutron_delete_port_raise_exception(self):
         """neutron delete port raises exception."""
         k_id = port_id
-        self.vimconn.neutron.list_ports.return_value = {
-            "ports": [{"id": port_id}, {"id": port2_id}]
-        }
         self.vimconn.neutron.delete_port.side_effect = nvExceptions.ClientException(
             "Connection aborted."
         )
         self.vimconn._delete_ports_by_id_wth_neutron(k_id)
-        self.vimconn.neutron.list_ports.assert_called_once()
         self.vimconn.neutron.delete_port.assert_called_once_with(k_id)
         self.vimconn.logger.error.assert_called_once_with(
             "Error deleting port: ClientException: Unknown Error (HTTP Connection aborted.)"
@@ -4196,7 +4373,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
-    def test_delete_created_items_delete_vol_raises(
+    def test_delete_created_items__delete_vol_raises_connection_error__operation_fails(
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
@@ -4212,15 +4389,16 @@ class TestNewVmInstance(unittest.TestCase):
             ("floating_ip", f"{floating_network_vim_id}"),
             ("volume", f"{volume_id}"),
         ]
-        mock_delete_volumes_by_id_wth_cinder.side_effect = ConnectionError(
-            "Connection failed."
+        mock_delete_volumes_by_id_wth_cinder.side_effect = (
+            neExceptions.ConnectionFailed("Connection failed.")
         )
         volumes_to_hold = []
         keep_waiting = False
-        result = self.vimconn._delete_created_items(
-            created_items, volumes_to_hold, keep_waiting
-        )
-        self.assertEqual(result, False)
+        with self.assertRaises(VimConnConnectionException):
+            result = self.vimconn._delete_created_items(
+                created_items, volumes_to_hold, keep_waiting
+            )
+            self.assertEqual(result, None)
         self.assertEqual(mock_get_item_name_id.call_count, 2)
         mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
             f"volume:{volume_id}", f"{volume_id}", [], created_items
@@ -4237,7 +4415,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
-    def test_delete_created_items_delete_fip_raises(
+    def test_delete_created_items__delete_fip_raises_connection_error__operation_fails(
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
@@ -4259,14 +4437,13 @@ class TestNewVmInstance(unittest.TestCase):
         )
         volumes_to_hold = []
         keep_waiting = True
-        result = self.vimconn._delete_created_items(
-            created_items, volumes_to_hold, keep_waiting
-        )
-        self.assertEqual(result, True)
-        self.assertEqual(mock_get_item_name_id.call_count, 2)
-        mock_delete_volumes_by_id_wth_cinder.assert_called_once_with(
-            f"volume:{volume_id}", f"{volume_id}", [], created_items
-        )
+        with self.assertRaises(VimConnConnectionException):
+            result = self.vimconn._delete_created_items(
+                created_items, volumes_to_hold, keep_waiting
+            )
+            self.assertEqual(result, None)
+        self.assertEqual(mock_get_item_name_id.call_count, 1)
+        mock_delete_volumes_by_id_wth_cinder.assert_not_called()
         mock_delete_floating_ip_by_id.assert_called_once_with(
             f"floating_ip:{floating_network_vim_id}",
             f"{floating_network_vim_id}",
@@ -4279,7 +4456,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
     @patch.object(vimconnector, "_delete_floating_ip_by_id")
-    def test_delete_created_items_get_item_name_raises(
+    def test_delete_created_items_get_item_name_raises_type_error__operation_fails(
         self,
         mock_delete_floating_ip_by_id,
         mock_delete_volumes_by_id_wth_cinder,
@@ -4297,19 +4474,16 @@ class TestNewVmInstance(unittest.TestCase):
         ]
         volumes_to_hold = []
         keep_waiting = False
-        result = self.vimconn._delete_created_items(
-            created_items, volumes_to_hold, keep_waiting
-        )
-        self.assertEqual(result, False)
-        self.assertEqual(mock_get_item_name_id.call_count, 2)
+        with self.assertRaises(VimConnException):
+            result = self.vimconn._delete_created_items(
+                created_items, volumes_to_hold, keep_waiting
+            )
+            self.assertEqual(result, None)
+        self.assertEqual(mock_get_item_name_id.call_count, 1)
         mock_delete_volumes_by_id_wth_cinder.assert_not_called()
         mock_delete_floating_ip_by_id.assert_not_called()
         _call_logger = self.vimconn.logger.error.call_args_list
         self.assertEqual(_call_logger[0][0], ("Error deleting 3: Invalid Type",))
-        self.assertEqual(
-            _call_logger[1][0],
-            (f"Error deleting volume{volume_id}: Invalid attribute",),
-        )
 
     @patch.object(vimconnector, "_get_item_name_id")
     @patch.object(vimconnector, "_delete_volumes_by_id_wth_cinder")
@@ -4479,16 +4653,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_extract_items_wth_keep_raises(
+    def test_delete_vminstance__extract_items_wth_keep_raises_attributeerror__raise_vimconnexception(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4504,7 +4676,7 @@ class TestNewVmInstance(unittest.TestCase):
         mock_extract_items_wth_keep_flag_from_created_items.side_effect = AttributeError
         volumes_to_hold = []
         mock_delete_created_items.return_value = False
-        with self.assertRaises(AttributeError):
+        with self.assertRaises(VimConnException):
             self.vimconn.delete_vminstance(
                 vm_id, initial_created_items, volumes_to_hold
             )
@@ -4513,7 +4685,6 @@ class TestNewVmInstance(unittest.TestCase):
         self.vimconn.nova.servers.delete.assert_not_called()
         mock_delete_created_items.assert_not_called()
         mock_sleep.assert_not_called()
-        mock_format_exception.assert_not_called()
         mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
             initial_created_items
         )
@@ -4524,7 +4695,7 @@ class TestNewVmInstance(unittest.TestCase):
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_delete_created_items_raises(
+    def test_delete_vminstance__delete_created_items_returns_true__delete_created_items_called_several_times(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
@@ -4539,15 +4710,12 @@ class TestNewVmInstance(unittest.TestCase):
         mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
         mock_sleep = MagicMock()
         volumes_to_hold = []
-        err = ConnectionError("ClientException occurred.")
-        mock_delete_created_items.side_effect = err
-        with self.assertRaises(ConnectionError) as err:
-            self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
+        mock_delete_created_items.side_effect = [True, False]
+        self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
-        mock_delete_created_items.assert_called_once()
+        self.assertEqual(mock_delete_created_items.call_count, 2)
         mock_sleep.assert_not_called()
         mock_extract_items_wth_keep_flag_from_created_items.assert_called_once_with(
             created_items
@@ -4555,16 +4723,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_delete_vm_ports_raises(
+    def test_delete_vminstance__delete_vm_ports_raises_connection_error__raise_vimconnconnectionexception(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4575,10 +4741,9 @@ class TestNewVmInstance(unittest.TestCase):
         volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
         err = ConnectionError("ClientException occurred.")
         mock_delete_vm_ports_attached_to_network.side_effect = err
-        mock_delete_created_items.side_effect = err
-        with self.assertRaises(ConnectionError) as err:
+        mock_delete_created_items.return_value = False
+        with self.assertRaises(VimConnConnectionException):
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_not_called()
@@ -4590,16 +4755,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_nova_server_delete_raises(
+    def test_delete_vminstance__nova_server_delete_raises_clientexception__raise_vimconn_unexpected_response(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4608,12 +4771,11 @@ class TestNewVmInstance(unittest.TestCase):
         created_items = deepcopy(created_items_all_true)
         mock_extract_items_wth_keep_flag_from_created_items.return_value = created_items
         volumes_to_hold = [f"{volume_id}", f"{volume_id2}"]
-        err = VimConnConnectionException("ClientException occurred.")
+        err = nvExceptions.ClientException("ClientException occurred.")
         self.vimconn.nova.servers.delete.side_effect = err
         mock_delete_created_items.side_effect = err
-        with self.assertRaises(VimConnConnectionException) as err:
+        with self.assertRaises(VimConnUnexpectedResponse):
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_called_once_with(created_items)
         self.vimconn.nova.servers.delete.assert_called_once_with(vm_id)
@@ -4625,16 +4787,14 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch("time.sleep")
     @patch.object(vimconnector, "_extract_items_wth_keep_flag_from_created_items")
-    @patch.object(vimconnector, "_format_exception")
     @patch.object(vimconnector, "_reload_connection")
     @patch.object(vimconnector, "_delete_vm_ports_attached_to_network")
     @patch.object(vimconnector, "_delete_created_items")
-    def test_delete_vminstance_reload_connection_raises(
+    def test_delete_vminstance__reload_connection_raises_connection_error__raises_vimconnconnection_exception(
         self,
         mock_delete_created_items,
         mock_delete_vm_ports_attached_to_network,
         mock_reload_connection,
-        mock_format_exception,
         mock_extract_items_wth_keep_flag_from_created_items,
         mock_sleep,
     ):
@@ -4647,9 +4807,8 @@ class TestNewVmInstance(unittest.TestCase):
         err = ConnectionError("ClientException occurred.")
         mock_delete_created_items.return_value = False
         mock_reload_connection.side_effect = err
-        with self.assertRaises(ConnectionError) as err:
+        with self.assertRaises(VimConnConnectionException):
             self.vimconn.delete_vminstance(vm_id, created_items, volumes_to_hold)
-            self.assertEqual(str(err), "ClientException occurred.")
         mock_reload_connection.assert_called_once()
         mock_delete_vm_ports_attached_to_network.assert_not_called()
         self.vimconn.nova.servers.delete.assert_not_called()
@@ -4895,7 +5054,18 @@ class TestNewVmInstance(unittest.TestCase):
 
     @patch.object(vimconnector, "_reload_connection", new_callable=CopyingMock())
     def test_get_monitoring_data(self, mock_reload_conection):
-        servers = ["server1", "server2"]
+        flavors = [
+            {"original_name": "flavor1", "id": "367fc1eb-bd22-40f8-a519-ed2fb4e5976b"},
+            {"original_name": "flavor2", "id": "5dcf9732-d17d-40b3-910d-37fc4c5aacc0"},
+        ]
+        servers = [
+            Server(
+                "server1", "ACTIVE", flavors[0], "312200db-42e3-4772-9518-d5db85468392"
+            ),
+            Server(
+                "server2", "ACTIVE", flavors[1], "39a166cf-e4e6-479c-b88c-9ad558cf2cbf"
+            ),
+        ]
         ports = {"ports": ["port1", "port2"]}
         self.vimconn.nova.servers.list.return_value = servers
         self.vimconn.neutron.list_ports.return_value = ports