Refactor resource creation and cleanup in rally 31/41931/3
authorJuha Kosonen <juha.kosonen@nokia.com>
Thu, 14 Sep 2017 08:23:56 +0000 (11:23 +0300)
committerJuha Kosonen <juha.kosonen@nokia.com>
Fri, 15 Sep 2017 07:23:15 +0000 (10:23 +0300)
Use SNAPS to create and delete resources.

Change-Id: Ic4d390382acea2be196e8a7518cb8cce25276a45
Signed-off-by: Juha Kosonen <juha.kosonen@nokia.com>
functest/ci/config_functest.yaml
functest/opnfv_tests/openstack/rally/rally.py
functest/tests/unit/openstack/rally/test_rally.py

index cfcc728..ee22aa2 100644 (file)
@@ -129,6 +129,7 @@ tempest:
     volume_device_name: vdc
 
 rally:
+    unique_names: True
     deployment_name: opnfv-rally
     network_name: rally-net
     subnet_name: rally-subnet
index 8c48254..5aba388 100644 (file)
@@ -18,6 +18,7 @@ import os
 import re
 import subprocess
 import time
+import uuid
 
 import iniparse
 import pkg_resources
@@ -25,13 +26,19 @@ import yaml
 
 from functest.core import testcase
 from functest.energy import energy
+from functest.opnfv_tests.openstack.snaps import snaps_utils
 from functest.utils.constants import CONST
-import functest.utils.openstack_utils as os_utils
+
+from snaps.openstack.create_image import ImageSettings
+from snaps.openstack.create_network import NetworkSettings, SubnetSettings
+from snaps.openstack.create_router import RouterSettings
+from snaps.openstack.tests import openstack_tests
+from snaps.openstack.utils import deploy_utils
 
 LOGGER = logging.getLogger(__name__)
 
 
-class RallyBase(testcase.OSGCTestCase):
+class RallyBase(testcase.TestCase):
     """Base class form Rally testcases implementation."""
 
     TESTS = ['authenticate', 'glance', 'ceilometer', 'cinder', 'heat',
@@ -42,6 +49,7 @@ class RallyBase(testcase.OSGCTestCase):
         CONST.__getattribute__('dir_functest_images'),
         GLANCE_IMAGE_FILENAME)
     GLANCE_IMAGE_FORMAT = CONST.__getattribute__('openstack_image_disk_format')
+    GLANCE_IMAGE_USERNAME = CONST.__getattribute__('openstack_image_username')
     GLANCE_IMAGE_EXTRA_PROPERTIES = {}
     if hasattr(CONST, 'openstack_extra_properties'):
         GLANCE_IMAGE_EXTRA_PROPERTIES = CONST.__getattribute__(
@@ -74,16 +82,30 @@ class RallyBase(testcase.OSGCTestCase):
     def __init__(self, **kwargs):
         """Initialize RallyBase object."""
         super(RallyBase, self).__init__(**kwargs)
+        if 'os_creds' in kwargs:
+            self.os_creds = kwargs['os_creds']
+        else:
+            creds_override = None
+            if hasattr(CONST, 'snaps_os_creds_override'):
+                creds_override = CONST.__getattribute__(
+                    'snaps_os_creds_override')
+
+            self.os_creds = openstack_tests.get_credentials(
+                os_env_file=CONST.__getattribute__('openstack_creds'),
+                overrides=creds_override)
+
+        self.guid = ''
+        if CONST.__getattribute__('rally_unique_names'):
+            self.guid = '-' + str(uuid.uuid4())
+
+        self.creators = []
         self.mode = ''
         self.summary = []
         self.scenario_dir = ''
-        self.nova_client = os_utils.get_nova_client()
-        self.neutron_client = os_utils.get_neutron_client()
-        self.network_dict = {}
+        self.ext_net_name = None
+        self.priv_net_id = None
         self.smoke = None
         self.test_name = None
-        self.image_exists = None
-        self.image_id = None
         self.start_time = None
         self.result = None
         self.details = None
@@ -103,13 +125,13 @@ class RallyBase(testcase.OSGCTestCase):
         task_args['concurrency'] = self.CONCURRENCY
         task_args['smoke'] = self.smoke
 
-        ext_net = os_utils.get_external_net(self.neutron_client)
+        ext_net = self.ext_net_name
         if ext_net:
             task_args['floating_network'] = str(ext_net)
         else:
             task_args['floating_network'] = ''
 
-        net_id = self.network_dict['net_id']
+        net_id = self.priv_net_id
         if net_id:
             task_args['netid'] = str(net_id)
         else:
@@ -445,25 +467,49 @@ class RallyBase(testcase.OSGCTestCase):
         if self.test_name not in self.TESTS:
             raise Exception("Test name '%s' is invalid" % self.test_name)
 
+        image_name = self.GLANCE_IMAGE_NAME + self.guid
+        network_name = self.RALLY_PRIVATE_NET_NAME + self.guid
+        subnet_name = self.RALLY_PRIVATE_SUBNET_NAME + self.guid
+        router_name = self.RALLY_ROUTER_NAME + self.guid
+        self.ext_net_name = snaps_utils.get_ext_net_name(self.os_creds)
+
         LOGGER.debug('Getting or creating image...')
-        self.image_exists, self.image_id = os_utils.get_or_create_image(
-            self.GLANCE_IMAGE_NAME,
-            self.GLANCE_IMAGE_PATH,
-            self.GLANCE_IMAGE_FORMAT,
-            self.GLANCE_IMAGE_EXTRA_PROPERTIES)
-        if self.image_id is None:
+        image_creator = deploy_utils.create_image(
+            self.os_creds, ImageSettings(
+                name=image_name,
+                image_file=self.GLANCE_IMAGE_PATH,
+                img_format=self.GLANCE_IMAGE_FORMAT,
+                image_user=self.GLANCE_IMAGE_USERNAME,
+                public=True,
+                extra_properties=self.GLANCE_IMAGE_EXTRA_PROPERTIES))
+        if image_creator is None:
             raise Exception("Failed to get or create image '%s'" %
-                            self.GLANCE_IMAGE_NAME)
-
-        LOGGER.debug("Creating network '%s'...", self.RALLY_PRIVATE_NET_NAME)
-        self.network_dict = os_utils.create_shared_network_full(
-            self.RALLY_PRIVATE_NET_NAME,
-            self.RALLY_PRIVATE_SUBNET_NAME,
-            self.RALLY_ROUTER_NAME,
-            self.RALLY_PRIVATE_SUBNET_CIDR)
-        if self.network_dict is None:
-            raise Exception("Failed to create shared network '%s'" %
-                            self.RALLY_PRIVATE_NET_NAME)
+                            image_name)
+        self.creators.append(image_creator)
+
+        LOGGER.debug("Creating network '%s'...", network_name)
+        network_creator = deploy_utils.create_network(
+            self.os_creds, NetworkSettings(
+                name=network_name,
+                shared=True,
+                subnet_settings=[SubnetSettings(
+                    name=subnet_name,
+                    cidr=self.RALLY_PRIVATE_SUBNET_CIDR)
+                ]))
+        if network_creator is None:
+            raise Exception("Failed to create private network")
+        self.priv_net_id = network_creator.get_network().id
+        self.creators.append(network_creator)
+
+        LOGGER.debug("Creating router '%s'...", router_name)
+        router_creator = deploy_utils.create_router(
+            self.os_creds, RouterSettings(
+                name=router_name,
+                external_gateway=self.ext_net_name,
+                internal_subnets=[subnet_name]))
+        if router_creator is None:
+            raise Exception("Failed to create router")
+        self.creators.append(router_creator)
 
     def _run_tests(self):
         if self.test_name == 'all':
@@ -545,12 +591,11 @@ class RallyBase(testcase.OSGCTestCase):
                     self.case_name, success_rate)
 
     def _clean_up(self):
-        if not self.image_exists:
-            LOGGER.debug("Deleting image '%s' with ID '%s'...",
-                         self.GLANCE_IMAGE_NAME, self.image_id)
-            if not os_utils.delete_glance_image(self.nova_client,
-                                                self.image_id):
-                LOGGER.error("Error deleting the glance image")
+        for creator in reversed(self.creators):
+            try:
+                creator.clean()
+            except Exception as e:
+                LOGGER.error('Unexpected error cleaning - %s', e)
 
     @energy.enable_recording
     def run(self, **kwargs):
@@ -560,11 +605,12 @@ class RallyBase(testcase.OSGCTestCase):
             self._prepare_env()
             self._run_tests()
             self._generate_report()
-            self._clean_up()
             res = testcase.TestCase.EX_OK
         except Exception as exc:   # pylint: disable=broad-except
             LOGGER.error('Error with run: %s', exc)
             res = testcase.TestCase.EX_RUN_ERROR
+        finally:
+            self._clean_up()
 
         self.stop_time = time.time()
         return res
index 95222ca..63c0192 100644 (file)
@@ -16,35 +16,31 @@ from functest.core import testcase
 from functest.opnfv_tests.openstack.rally import rally
 from functest.utils.constants import CONST
 
+from snaps.openstack.os_credentials import OSCreds
+
 
 class OSRallyTesting(unittest.TestCase):
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'get_nova_client', return_value=mock.Mock())
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'get_neutron_client', return_value=mock.Mock())
-    def setUp(self, mock_func1, mock_func2):
-        self.rally_base = rally.RallyBase()
-        self.rally_base.network_dict['net_id'] = 'test_net_id'
-        self.polling_iter = 2
-        mock_func1.assert_called()
-        mock_func2.assert_called()
-
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'get_external_net', return_value=None)
-    def test_build_task_args_missing_floating_network(self, mock_func):
+    def setUp(self):
+        os_creds = OSCreds(
+            username='user', password='pass',
+            auth_url='http://foo.com:5000/v3', project_name='bar')
+        with mock.patch('snaps.openstack.tests.openstack_tests.'
+                        'get_credentials', return_value=os_creds) as m:
+            self.rally_base = rally.RallyBase()
+            self.polling_iter = 2
+        self.assertTrue(m.called)
+
+    def test_build_task_args_missing_floating_network(self):
         CONST.__setattr__('OS_AUTH_URL', None)
+        self.rally_base.ext_net_name = ''
         task_args = self.rally_base._build_task_args('test_file_name')
         self.assertEqual(task_args['floating_network'], '')
-        mock_func.assert_called()
 
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'get_external_net', return_value='test_floating_network')
-    def test_build_task_args_missing_net_id(self, mock_func):
+    def test_build_task_args_missing_net_id(self):
         CONST.__setattr__('OS_AUTH_URL', None)
-        self.rally_base.network_dict['net_id'] = ''
+        self.rally_base.priv_net_id = ''
         task_args = self.rally_base._build_task_args('test_file_name')
         self.assertEqual(task_args['netid'], '')
-        mock_func.assert_called()
 
     @staticmethod
     def check_scenario_file(value):
@@ -284,27 +280,53 @@ class OSRallyTesting(unittest.TestCase):
         with self.assertRaises(Exception):
             self.rally_base._prepare_env()
 
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'get_or_create_image', return_value=(True, None))
-    def test_prepare_env_image_missing(self, mock_get_img):
+    @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
+                'get_ext_net_name', return_value='test_net_name')
+    @mock.patch('snaps.openstack.utils.deploy_utils.create_image',
+                return_value=None)
+    def test_prepare_env_image_missing(self, mock_get_img, mock_get_net):
         self.rally_base.TESTS = ['test1', 'test2']
         self.rally_base.test_name = 'test1'
         with self.assertRaises(Exception):
             self.rally_base._prepare_env()
         mock_get_img.assert_called()
+        mock_get_net.assert_called()
 
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'get_or_create_image', return_value=(True, 'image_id'))
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'create_shared_network_full', return_value=None)
-    def test_prepare_env_image_shared_network_creation_failed(
-            self, mock_create_net, mock_get_img):
+    @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
+                'get_ext_net_name', return_value='test_net_name')
+    @mock.patch('snaps.openstack.utils.deploy_utils.create_image',
+                return_value=mock.Mock())
+    @mock.patch('snaps.openstack.utils.deploy_utils.create_network',
+                return_value=None)
+    def test_prepare_env_network_creation_failed(
+            self, mock_create_net, mock_get_img, mock_get_net):
+        self.rally_base.TESTS = ['test1', 'test2']
+        self.rally_base.test_name = 'test1'
+        with self.assertRaises(Exception):
+            self.rally_base._prepare_env()
+        mock_create_net.assert_called()
+        mock_get_img.assert_called()
+        mock_get_net.assert_called()
+
+    @mock.patch('functest.opnfv_tests.openstack.snaps.snaps_utils.'
+                'get_ext_net_name', return_value='test_net_name')
+    @mock.patch('snaps.openstack.utils.deploy_utils.create_image',
+                return_value=mock.Mock())
+    @mock.patch('snaps.openstack.utils.deploy_utils.create_network',
+                return_value=mock.Mock())
+    @mock.patch('snaps.openstack.utils.deploy_utils.create_router',
+                return_value=None)
+    def test_prepare_env_router_creation_failed(
+            self, mock_create_router, mock_create_net, mock_get_img,
+            mock_get_net):
         self.rally_base.TESTS = ['test1', 'test2']
         self.rally_base.test_name = 'test1'
         with self.assertRaises(Exception):
             self.rally_base._prepare_env()
         mock_create_net.assert_called()
         mock_get_img.assert_called()
+        mock_get_net.assert_called()
+        mock_create_router.assert_called()
 
     @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
                 '_run_task', return_value=mock.Mock())
@@ -323,16 +345,13 @@ class OSRallyTesting(unittest.TestCase):
         self.rally_base._run_tests()
         mock_run_task.assert_any_call('test1')
 
-    @mock.patch('functest.opnfv_tests.openstack.rally.rally.os_utils.'
-                'delete_glance_image')
-    def test_clean_up_default(self, mock_glance_method):
-        self.rally_base.cinder_client = mock.Mock()
-        self.rally_base.image_exists = False
-        self.rally_base.image_id = 1
-        self.rally_base.nova_client = mock.Mock()
+    def test_clean_up_default(self):
+        creator1 = mock.Mock()
+        creator2 = mock.Mock()
+        self.rally_base.creators = [creator1, creator2]
         self.rally_base._clean_up()
-        mock_glance_method.assert_any_call(self.rally_base.nova_client,
-                                           1)
+        self.assertTrue(creator1.clean.called)
+        self.assertTrue(creator2.clean.called)
 
     @mock.patch('functest.opnfv_tests.openstack.rally.rally.RallyBase.'
                 '_prepare_env')