Feature 10911-Vertical scaling of VM instances from OSM
[osm/RO.git] / NG-RO / osm_ng_ro / tests / test_ns_thread.py
index 16b98e7..c1d23a0 100644 (file)
 #######################################################################################
 
 import logging
-from types import ModuleType
 import unittest
-from unittest.mock import Mock, patch
+from unittest.mock import MagicMock, patch
 
-from osm_ng_ro.ns_thread import VimInteractionNet
+from osm_ng_ro.ns_thread import (
+    VimInteractionAffinityGroup,
+    VimInteractionNet,
+    VimInteractionResize,
+)
+from osm_ro_plugin.vimconn import VimConnConnectionException, VimConnException
 
 
 class TestVimInteractionNet(unittest.TestCase):
-    @classmethod
-    def setUpClass(cls):
+    def setUp(self):
         module_name = "osm_ro_plugin"
-        osm_ro_plugin = ModuleType(module_name)
-        osm_ro_plugin.vimconn = Mock(name=module_name + ".vimconn")
-        osm_ro_plugin.vimconn.VimConnector = Mock(
-            name=module_name + "vimconn.VimConnector"
-        )
-        osm_ro_plugin.vimconn.VimConnException = Mock(
-            name=module_name + ".vimconn.VimConnException"
-        )
-        cls.target_vim = osm_ro_plugin.vimconn.VimConnector
-        cls.VimConnException = osm_ro_plugin.vimconn.VimConnException
-        cls.task_depends = None
+        self.target_vim = MagicMock(name=f"{module_name}.vimconn.VimConnector")
+        self.task_depends = None
+
+        patches = [patch(f"{module_name}.vimconn.VimConnector", self.target_vim)]
 
-    @classmethod
-    def tearDownClass(cls):
-        del cls.target_vim
-        del cls.task_depends
-        del cls.VimConnException
+        # Enabling mocks and add cleanups
+        for mock in patches:
+            mock.start()
+            self.addCleanup(mock.stop)
 
     def test__mgmt_net_id_in_find_params_mgmt_several_vim_nets(self):
         """
-        management_network_id in find_params.get('mgmt')
+        mgmt network is set in find_params
+        management_network_id in vim config
         More than one network found in the VIM
         """
         db = "test_db"
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_2": {
+            0: {
                 "config": {
                     "management_network_id": "test_mgmt_id",
                 },
@@ -64,12 +60,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_2": {
-                        "target_id": "vim_openstack_2",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -79,7 +75,7 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "",
+                        "params": {},
                         "find_params": {
                             "mgmt": True,
                             "name": "some_mgmt_name",
@@ -108,14 +104,15 @@ class TestVimInteractionNet(unittest.TestCase):
 
     def test__mgmt_net_id_in_find_params_mgmt_no_vim_nets(self):
         """
-        management_network_id in find_params.get('mgmt')
+        mgmt network is set in find_params
+        management_network_id in vim config
         The network could not be found in the VIM
         """
         db = "test_db"
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_3": {
+            0: {
                 "config": {
                     "management_network_id": "test_mgmt_id",
                 },
@@ -124,13 +121,13 @@ class TestVimInteractionNet(unittest.TestCase):
 
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
-            instance, "logger", logging
-        ):
+            instance, "db_vims", db_vims
+        ), patch.object(instance, "logger", logging):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_3": {
-                        "target_id": "vim_openstack_3",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -139,7 +136,7 @@ class TestVimInteractionNet(unittest.TestCase):
                         "item": "test_item",
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
-                        "params": "",
+                        "params": {},
                         # values coming from extra_dict
                         "find_params": {
                             "mgmt": True,
@@ -164,16 +161,74 @@ class TestVimInteractionNet(unittest.TestCase):
                 self.assertEqual(result[1].get("created"), False)
                 self.assertEqual(result[1].get("vim_status"), "VIM_ERROR")
 
+    def test__mgmt_net_in_find_params_no_vim_config_no_vim_nets(self):
+        """
+        mgmt network is set in find_params
+        vim config does not have management_network_id or management_network_id
+        The network could not be found in the VIM
+        """
+        db = "test_db"
+        logger = "test_logger"
+        my_vims = "test-vim"
+        db_vims = {
+            0: {
+                "config": {},
+            },
+        }
+
+        instance = VimInteractionNet(db, logger, my_vims, db_vims)
+        with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
+            instance, "db_vims", db_vims
+        ), patch.object(instance, "logger", logging):
+            ro_task = {
+                "target_id": 0,
+                "tasks": {
+                    "task_index_3": {
+                        "target_id": 0,
+                        "action_id": "123456",
+                        "nsr_id": "654321",
+                        "task_id": "123456:1",
+                        "status": "SCHEDULED",
+                        "action": "CREATE",
+                        "item": "test_item",
+                        "target_record": "test_target_record",
+                        "target_record_id": "test_target_record_id",
+                        "params": {},
+                        # values coming from extra_dict
+                        "find_params": {
+                            "mgmt": True,
+                            "name": "some_mgmt_name",
+                        },
+                        "depends_on": "test_depends_on",
+                    },
+                },
+            }
+
+            task_index = "task_index_3"
+            self.target_vim.get_network_list.return_value = []
+            self.target_vim.new_network.return_value = "sample_net_id", {
+                "item1": "sample_created_item"
+            }
+            result = instance.new(ro_task, task_index, self.task_depends)
+            self.assertEqual(result[0], "BUILD")
+            self.assertEqual(result[1].get("vim_id"), "sample_net_id")
+            self.assertEqual(result[1].get("created"), True)
+            self.assertDictEqual(
+                result[1].get("created_items"), {"item1": "sample_created_item"}
+            )
+            self.assertEqual(result[1].get("vim_status"), "BUILD")
+
     def test__mgmt_net_name_in_find_params_mgmt_several_vim_nets(self):
         """
-        management_network_name in find_params.get('mgmt')
+        mgmt network is set in find_params
+        management_network_name in vim config
         More than one network found in the VIM
         """
         db = "test_db"
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_4": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -183,12 +238,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_4": {
-                        "target_id": "vim_openstack_4",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -198,7 +253,7 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "",
+                        "params": {},
                         "find_params": {
                             "mgmt": True,
                             "name": "some_mgmt_name",
@@ -227,14 +282,15 @@ class TestVimInteractionNet(unittest.TestCase):
 
     def test__mgmt_net_name_in_find_params_mgmt_no_vim_nets(self):
         """
-        management_network_name in find_params.get('mgmt')
+        mgmt network is set in find_params
+        management_network_name in vim config
         The network could not be found in the VIM
         """
         db = "test_db"
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_5": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -244,12 +300,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_5": {
-                        "target_id": "vim_openstack_5",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -259,7 +315,7 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "",
+                        "params": {},
                         "find_params": {
                             "mgmt": True,
                             "name": "some_mgmt_name",
@@ -285,14 +341,16 @@ class TestVimInteractionNet(unittest.TestCase):
 
     def test__mgmt_net_name_in_find_params_filterdict_several_vim_nets(self):
         """
-        management_network_name in find_params.get('filterdict')
+        mgmt network is set in find_params
+        management_network_name in vim config
+        network_name is set in find_params.get('filterdict')
         More than one network found in the VIM
         """
         db = "test_db"
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_6": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -301,12 +359,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_6": {
-                        "target_id": "vim_openstack_6",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -316,7 +374,7 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "",
+                        "params": {},
                         "find_params": {
                             "filter_dict": {
                                 "name": "some-network-name",
@@ -356,7 +414,7 @@ class TestVimInteractionNet(unittest.TestCase):
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_7": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -365,12 +423,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_4": {
-                        "target_id": "vim_openstack_7",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -380,7 +438,7 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "",
+                        "params": {},
                         "find_params": {"wrong_param": "wrong_value"},
                         "depends_on": "test_depends_on",
                     },
@@ -410,7 +468,7 @@ class TestVimInteractionNet(unittest.TestCase):
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_8": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -419,12 +477,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_8": {
-                        "target_id": "vim_openstack_8",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -434,7 +492,9 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "test_params",
+                        "params": {
+                            "net_name": "test_params",
+                        },
                         "find_params": {
                             "filter_dict": {
                                 "name": "some-network-name",
@@ -458,14 +518,16 @@ class TestVimInteractionNet(unittest.TestCase):
 
     def test__mgmt_net_name_in_find_params_filterdict_no_vim_nets(self):
         """
-        management_network_name in find_params.get('filterdict')
+        mgmt network is set in find_params
+        management_network_name in vim config
+        network_name is set in find_params.get('filterdict')
         Any network could not be found in the VIM
         """
         db = "test_db"
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_9": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -474,12 +536,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_9": {
-                        "target_id": "vim_openstack_9",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -516,9 +578,69 @@ class TestVimInteractionNet(unittest.TestCase):
                 self.assertEqual(result[1].get("created"), False)
                 self.assertEqual(result[1].get("vim_status"), "VIM_ERROR")
 
+    def test__mgmt_net_in_find_params_filterdict_no_config_no_vim_nets(self):
+        """
+        mgmt network is set in find_params
+        vim config is empty
+        network_name is set in find_params.get('filterdict')
+        Any network could not be found in the VIM
+        """
+        db = "test_db"
+        logger = "test_logger"
+        my_vims = "test-vim"
+        db_vims = {
+            0: {
+                "config": {},
+            },
+        }
+        instance = VimInteractionNet(db, logger, my_vims, db_vims)
+        with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
+            instance, "logger", logging
+        ), patch.object(instance, "db_vims", db_vims):
+            ro_task = {
+                "target_id": 0,
+                "tasks": {
+                    "task_index_9": {
+                        "target_id": 0,
+                        "action_id": "123456",
+                        "nsr_id": "654321",
+                        "task_id": "123456:1",
+                        "status": "SCHEDULED",
+                        "action": "CREATE",
+                        "item": "test_item",
+                        "target_record": "test_target_record",
+                        "target_record_id": "test_target_record_id",
+                        # values coming from extra_dict
+                        "params": {},
+                        "find_params": {
+                            "filter_dict": {
+                                "name": "some-network-name",
+                            },
+                            "mgmt": True,
+                            "name": "some_mgmt_name",
+                        },
+                        "depends_on": "test_depends_on",
+                    },
+                },
+            }
+
+            task_index = "task_index_9"
+            self.target_vim.get_network_list.return_value = []
+            with self.assertLogs() as captured:
+                result = instance.new(ro_task, task_index, self.task_depends)
+                self.assertEqual(len(captured.records), 1)
+                self.assertTrue(
+                    "Network not found with this criteria"
+                    in captured.records[0].getMessage()
+                )
+                self.assertEqual(captured.records[0].levelname, "ERROR")
+                self.assertEqual(result[0], "FAILED")
+                self.assertEqual(result[1].get("created"), False)
+                self.assertEqual(result[1].get("vim_status"), "VIM_ERROR")
+
     def test__mgmt_net_name_in_find_params_mgmt_no_config_one_vim_net(self):
         """
-        name in find_params
+        mgmt network is set in find_params
         management_network_name is not in db_vims.get('config')
         One network found in the VIM
         """
@@ -526,19 +648,19 @@ class TestVimInteractionNet(unittest.TestCase):
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_10": {
+            0: {
                 "config": {},
             },
         }
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_2": {
-                        "target_id": "vim_openstack_10",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -548,7 +670,7 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "",
+                        "params": {},
                         "find_params": {
                             "mgmt": True,
                             "name": "some_mgmt_name",
@@ -576,7 +698,7 @@ class TestVimInteractionNet(unittest.TestCase):
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_11": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -585,12 +707,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_11": {
-                        "target_id": "vim_openstack_11",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -631,7 +753,7 @@ class TestVimInteractionNet(unittest.TestCase):
         logger = "test_logger"
         my_vims = "test-vim"
         db_vims = {
-            "vim_openstack_13": {
+            0: {
                 "config": {
                     "management_network_name": "test_mgmt_name",
                 },
@@ -640,12 +762,12 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
             instance, "logger", logging
-        ):
+        ), patch.object(instance, "db_vims", db_vims):
             ro_task = {
                 "target_id": 0,
                 "tasks": {
                     "task_index_12": {
-                        "target_id": "vim_openstack_13",
+                        "target_id": 0,
                         "action_id": "123456",
                         "nsr_id": "654321",
                         "task_id": "123456:1",
@@ -655,15 +777,19 @@ class TestVimInteractionNet(unittest.TestCase):
                         "target_record": "test_target_record",
                         "target_record_id": "test_target_record_id",
                         # values coming from extra_dict
-                        "params": "",
+                        "params": {},
                         "depends_on": "test_depends_on",
                     },
                 },
             }
 
             task_index = "task_index_12"
-            with self.assertRaises(TypeError):
+            self.target_vim.new_network.side_effect = VimConnConnectionException(
+                "VimConnConnectionException occurred."
+            )
+            with self.assertLogs() as captured:
                 instance.new(ro_task, task_index, self.task_depends)
+                self.assertEqual(captured.records[0].levelname, "ERROR")
 
     def test__refresh_ro_task_vim_status_active(self):
         """
@@ -680,7 +806,9 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(
             instance, "my_vims", {"vim_openstack_1": self.target_vim}
-        ), patch.object(instance, "logger", logging):
+        ), patch.object(instance, "logger", logging), patch.object(
+            instance, "db_vims", db_vims
+        ):
             ro_task = {
                 "_id": "122436:1",
                 "locked_by": None,
@@ -693,6 +821,7 @@ class TestVimInteractionNet(unittest.TestCase):
                     "vim_name": "test-vim",
                     "vim_status": None,
                     "vim_details": "some-details",
+                    "vim_message": None,
                     "refresh_at": None,
                 },
                 "modified_at": 1637324200.994312,
@@ -732,7 +861,9 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(
             instance, "my_vims", {"vim_openstack_1": self.target_vim}
-        ), patch.object(instance, "logger", logging):
+        ), patch.object(instance, "logger", logging), patch.object(
+            instance, "db_vims", db_vims
+        ):
             ro_task = {
                 "_id": "122436:1",
                 "locked_by": None,
@@ -745,6 +876,7 @@ class TestVimInteractionNet(unittest.TestCase):
                     "vim_name": "test-vim",
                     "vim_status": "BUILD",
                     "vim_details": "",
+                    "vim_message": None,
                     "refresh_at": None,
                 },
                 "modified_at": 1637324200.994312,
@@ -785,7 +917,9 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(
             instance, "my_vims", {"vim_openstack_1": self.target_vim}
-        ), patch.object(instance, "logger", logging):
+        ), patch.object(instance, "logger", logging), patch.object(
+            instance, "db_vims", db_vims
+        ):
             ro_task = {
                 "_id": "122436:1",
                 "locked_by": None,
@@ -798,6 +932,7 @@ class TestVimInteractionNet(unittest.TestCase):
                     "vim_name": "test-vim",
                     "vim_status": "BUILD",
                     "vim_details": "",
+                    "vim_message": None,
                     "refresh_at": None,
                 },
                 "modified_at": 1637324200.994312,
@@ -817,13 +952,13 @@ class TestVimInteractionNet(unittest.TestCase):
             task_status = "FAILED"
             ro_vim_item_update = {
                 "vim_status": "ERROR",
-                "vim_details": "some error message",
+                "vim_message": "some error message",
             }
             result = instance.refresh(ro_task)
             self.assertEqual(result[0], task_status)
             self.assertDictEqual(result[1], ro_vim_item_update)
 
-    def test__refresh_ro_task_VimConnException_occured(self):
+    def test__refresh_ro_task_VimConnException_occurred(self):
         """
         vimconn.VimConnException has occured
         """
@@ -838,7 +973,9 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(
             instance, "my_vims", {"vim_openstack_1": self.target_vim}
-        ), patch.object(instance, "logger", logging):
+        ), patch.object(instance, "logger", logging), patch.object(
+            instance, "db_vims", db_vims
+        ):
             ro_task = {
                 "_id": "122436:1",
                 "locked_by": None,
@@ -851,6 +988,7 @@ class TestVimInteractionNet(unittest.TestCase):
                     "vim_name": "test-vim",
                     "vim_status": "BUILD",
                     "vim_details": "",
+                    "vim_message": None,
                     "refresh_at": None,
                 },
                 "modified_at": 1637324200.994312,
@@ -858,12 +996,12 @@ class TestVimInteractionNet(unittest.TestCase):
                 "to_check_at": 1637324200.994312,
                 "tasks": {},
             }
-            self.target_vim.refresh_nets_status.side_effect = Mock(
-                side_effect=self.VimConnException("VimConnException occured")
+            self.target_vim.refresh_nets_status.side_effect = VimConnException(
+                "VimConnException occurred."
             )
-            with self.assertRaises(TypeError):
+            with self.assertLogs() as captured:
                 instance.refresh(ro_task)
-            self.target_vim.refresh_nets_status.side_effect = None
+                self.assertEqual(captured.records[0].levelname, "ERROR")
 
     def test__refresh_ro_task_vim_status_deleted(self):
         """
@@ -880,7 +1018,9 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(
             instance, "my_vims", {"vim_openstack_1": self.target_vim}
-        ), patch.object(instance, "logger", logging):
+        ), patch.object(instance, "logger", logging), patch.object(
+            instance, "db_vims", db_vims
+        ):
             ro_task = {
                 "_id": "122436:1",
                 "locked_by": None,
@@ -893,6 +1033,7 @@ class TestVimInteractionNet(unittest.TestCase):
                     "vim_name": "test-vim",
                     "vim_status": "BUILD",
                     "vim_details": "",
+                    "vim_message": None,
                     "refresh_at": None,
                 },
                 "modified_at": 163724200.994312,
@@ -911,7 +1052,7 @@ class TestVimInteractionNet(unittest.TestCase):
             task_status = "FAILED"
             ro_vim_item_update = {
                 "vim_status": "DELETED",
-                "vim_details": "Deleted externally",
+                "vim_message": "Deleted externally",
                 "vim_id": None,
             }
             result = instance.refresh(ro_task)
@@ -934,7 +1075,9 @@ class TestVimInteractionNet(unittest.TestCase):
         instance = VimInteractionNet(db, logger, my_vims, db_vims)
         with patch.object(
             instance, "my_vims", {"vim_openstack_2": self.target_vim}
-        ), patch.object(instance, "logger", logging):
+        ), patch.object(instance, "logger", logging), patch.object(
+            instance, "db_vims", db_vims
+        ):
             ro_task = {
                 "_id": "128436:1",
                 "locked_by": None,
@@ -947,6 +1090,7 @@ class TestVimInteractionNet(unittest.TestCase):
                     "vim_name": "test-vim",
                     "vim_status": "BUILD",
                     "vim_details": "",
+                    "vim_message": None,
                     "refresh_at": None,
                 },
                 "modified_at": 163724211.994312,
@@ -957,3 +1101,271 @@ class TestVimInteractionNet(unittest.TestCase):
             self.target_vim.refresh_nets_status.return_value = {}
             with self.assertRaises(KeyError):
                 instance.refresh(ro_task)
+
+
+class TestVimInteractionAffinityGroup(unittest.TestCase):
+    def setUp(self):
+        module_name = "osm_ro_plugin"
+        self.target_vim = MagicMock(name=f"{module_name}.vimconn.VimConnector")
+        self.task_depends = None
+
+        patches = [patch(f"{module_name}.vimconn.VimConnector", self.target_vim)]
+
+        # Enabling mocks and add cleanups
+        for mock in patches:
+            mock.start()
+            self.addCleanup(mock.stop)
+
+    def test__new_affinity_group_ok(self):
+        """
+        create affinity group with attributes set in params
+        """
+        db = "test_db"
+        logger = "test_logger"
+        my_vims = "test-vim"
+        db_vims = {
+            0: {
+                "config": {},
+            },
+        }
+
+        instance = VimInteractionAffinityGroup(db, logger, my_vims, db_vims)
+        with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
+            instance, "logger", logging
+        ), patch.object(instance, "db_vims", db_vims):
+            ro_task = {
+                "target_id": 0,
+                "tasks": {
+                    "task_index_1": {
+                        "target_id": 0,
+                        "action_id": "123456",
+                        "nsr_id": "654321",
+                        "task_id": "123456:1",
+                        "status": "SCHEDULED",
+                        "action": "CREATE",
+                        "item": "test_item",
+                        "target_record": "test_target_record",
+                        "target_record_id": "test_target_record_id",
+                        # values coming from extra_dict
+                        "params": {
+                            "affinity_group_data": {
+                                "name": "affinity_group_1",
+                                "type": "affinity",
+                                "scope": "nfvi-node",
+                            }
+                        },
+                        "find_params": {},
+                        "depends_on": "test_depends_on",
+                    },
+                },
+            }
+
+            task_index = "task_index_1"
+            self.target_vim.new_affinity_group.return_value = (
+                "sample_affinity_group_id_1"
+            )
+            result = instance.new(ro_task, task_index, self.task_depends)
+            self.assertEqual(result[0], "DONE")
+            self.assertEqual(result[1].get("vim_id"), "sample_affinity_group_id_1")
+            self.assertEqual(result[1].get("created"), True)
+            self.assertEqual(result[1].get("vim_status"), "DONE")
+
+    def test__new_affinity_group_failed(self):
+        """
+        create affinity group with no attributes set in params
+        """
+        db = "test_db"
+        logger = "test_logger"
+        my_vims = "test-vim"
+        db_vims = {
+            0: {
+                "config": {},
+            },
+        }
+
+        instance = VimInteractionAffinityGroup(db, logger, my_vims, db_vims)
+        with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
+            instance, "logger", logging
+        ), patch.object(instance, "db_vims", db_vims):
+            ro_task = {
+                "target_id": 0,
+                "tasks": {
+                    "task_index_2": {
+                        "target_id": 0,
+                        "action_id": "123456",
+                        "nsr_id": "654321",
+                        "task_id": "123456:1",
+                        "status": "SCHEDULED",
+                        "action": "CREATE",
+                        "item": "test_item",
+                        "target_record": "test_target_record",
+                        "target_record_id": "test_target_record_id",
+                        # values coming from extra_dict
+                        "params": {},
+                        "find_params": {},
+                        "depends_on": "test_depends_on",
+                    },
+                },
+            }
+
+            task_index = "task_index_2"
+            self.target_vim.new_affinity_group.return_value = (
+                "sample_affinity_group_id_1"
+            )
+            result = instance.new(ro_task, task_index, self.task_depends)
+            self.assertEqual(result[0], "DONE")
+            self.assertEqual(result[1].get("vim_id"), None)
+            self.assertEqual(result[1].get("created"), False)
+            self.assertEqual(result[1].get("vim_status"), "DONE")
+
+    def test__delete_affinity_group_ok(self):
+        """
+        delete affinity group with a proper vim_id
+        """
+        db = "test_db"
+        logger = "test_logger"
+        my_vims = "test-vim"
+        db_vims = {
+            0: {
+                "config": {},
+            },
+        }
+
+        instance = VimInteractionAffinityGroup(db, logger, my_vims, db_vims)
+        with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
+            instance, "logger", logging
+        ), patch.object(instance, "db_vims", db_vims):
+            ro_task = {
+                "target_id": 0,
+                "tasks": {
+                    "task_index_3": {
+                        "target_id": 0,
+                        "task_id": "123456:1",
+                    },
+                },
+                "vim_info": {
+                    "created": False,
+                    "created_items": None,
+                    "vim_id": "sample_affinity_group_id_3",
+                    "vim_name": "sample_affinity_group_id_3",
+                    "vim_status": None,
+                    "vim_details": "some-details",
+                    "vim_message": None,
+                    "refresh_at": None,
+                },
+            }
+
+            task_index = "task_index_3"
+            self.target_vim.delete_affinity_group.return_value = (
+                "sample_affinity_group_id_3"
+            )
+            result = instance.delete(ro_task, task_index)
+            self.assertEqual(result[0], "DONE")
+            self.assertEqual(result[1].get("vim_message"), "DELETED")
+            self.assertEqual(result[1].get("created"), False)
+            self.assertEqual(result[1].get("vim_status"), "DELETED")
+
+    def test__delete_affinity_group_failed(self):
+        """
+        delete affinity group with missing vim_id
+        """
+        db = "test_db"
+        logger = "test_logger"
+        my_vims = "test-vim"
+        db_vims = {
+            0: {
+                "config": {},
+            },
+        }
+
+        instance = VimInteractionAffinityGroup(db, logger, my_vims, db_vims)
+        with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
+            instance, "logger", logging
+        ), patch.object(instance, "db_vims", db_vims):
+            ro_task = {
+                "target_id": 0,
+                "tasks": {
+                    "task_index_4": {
+                        "target_id": 0,
+                        "task_id": "123456:1",
+                    },
+                },
+                "vim_info": {
+                    "created": False,
+                    "created_items": None,
+                    "vim_id": None,
+                    "vim_name": None,
+                    "vim_status": None,
+                    "vim_details": "some-details",
+                    "vim_message": None,
+                    "refresh_at": None,
+                },
+            }
+
+            task_index = "task_index_4"
+            self.target_vim.delete_affinity_group.return_value = ""
+            result = instance.delete(ro_task, task_index)
+            self.assertEqual(result[0], "DONE")
+            self.assertEqual(result[1].get("vim_message"), "DELETED")
+            self.assertEqual(result[1].get("created"), False)
+            self.assertEqual(result[1].get("vim_status"), "DELETED")
+
+
+class TestVimInteractionResize(unittest.TestCase):
+    def setUp(self):
+        module_name = "osm_ro_plugin"
+        self.target_vim = MagicMock(name=f"{module_name}.vimconn.VimConnector")
+        self.task_depends = None
+
+        patches = [patch(f"{module_name}.vimconn.VimConnector", self.target_vim)]
+
+        # Enabling mocks and add cleanups
+        for mock in patches:
+            mock.start()
+            self.addCleanup(mock.stop)
+
+    def test__exec_resize_done(self):
+        """
+        create verticalscale task
+        """
+        db = "test_db"
+        logger = "test_logger"
+        my_vims = "test-vim"
+        db_vims = {
+            0: {
+                "config": {},
+            },
+        }
+        target_record_id = (
+            "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:"
+            "vdur.bb9c43f9-10a2-4569-a8a8-957c3528b6d1"
+        )
+
+        instance = VimInteractionResize(db, logger, my_vims, db_vims)
+        with patch.object(instance, "my_vims", [self.target_vim]), patch.object(
+            instance, "logger", logging
+        ), patch.object(instance, "db_vims", db_vims):
+            ro_task = {
+                "target_id": 0,
+                "tasks": {
+                    "task_index_1": {
+                        "target_id": 0,
+                        "action_id": "bb937f49-3870-4169-b758-9732e1ff40f3",
+                        "nsr_id": "993166fe-723e-4680-ac4b-b1af2541ae31",
+                        "task_id": "bb937f49-3870-4169-b758-9732e1ff40f3:0",
+                        "status": "SCHEDULED",
+                        "action": "EXEC",
+                        "item": "verticalscale",
+                        "target_record": "vnfrs:665b4165-ce24-4320-bf19-b9a45bade49f:vdur.0",
+                        "target_record_id": target_record_id,
+                        "params": {
+                            "vim_vm_id": "f37b18ef-3caa-4dc9-ab91-15c669b16396",
+                            "flavor_dict": "flavor_dict",
+                        },
+                    }
+                },
+            }
+            task_index = "task_index_1"
+            result = instance.exec(ro_task, task_index, self.task_depends)
+            self.assertEqual(result[0], "DONE")
+            self.assertEqual(result[1].get("vim_status"), "DONE")