Merge "Update unit test related to vyos_vrouter"
[functest.git] / functest / opnfv_tests / openstack / refstack_client / refstack_client.py
old mode 100755 (executable)
new mode 100644 (file)
index 2a2718d..42befe2
@@ -1,13 +1,15 @@
 #!/usr/bin/env python
 
-# matthew.lijun@huawei.com wangwulin@huawei.com
+# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
+#
 # All rights reserved. This program and the accompanying materials
 # are made available under the terms of the Apache License, Version 2.0
 # which accompanies this distribution, and is available at
 # http://www.apache.org/licenses/LICENSE-2.0
 
-from __future__ import division
+"""Refstack client testcase implemenation."""
 
+from __future__ import division
 
 import argparse
 import logging
@@ -17,121 +19,128 @@ import sys
 import subprocess
 import time
 
+import pkg_resources
+
 from functest.core import testcase
+from functest.energy import energy
+from functest.opnfv_tests.openstack.refstack_client.tempest_conf \
+    import TempestConf
 from functest.opnfv_tests.openstack.tempest import conf_utils
 from functest.utils.constants import CONST
 import functest.utils.functest_utils as ft_utils
-from tempest_conf import TempestConf
 
-""" logging configuration """
-logger = logging.getLogger(__name__)
+__author__ = ("Matthew Li <matthew.lijun@huawei.com>,"
+              "Linda Wang <wangwulin@huawei.com>")
+
+# logging configuration """
+LOGGER = logging.getLogger(__name__)
 
 
 class RefstackClient(testcase.TestCase):
+    """RefstackClient testcase implementation class."""
 
     def __init__(self, **kwargs):
+        """Initialize RefstackClient testcase object."""
         if "case_name" not in kwargs:
             kwargs["case_name"] = "refstack_defcore"
         super(RefstackClient, self).__init__(**kwargs)
-        self.FUNCTEST_TEST = CONST.dir_functest_test
-        self.CONF_PATH = CONST.refstack_tempest_conf_path
-        self.DEFCORE_LIST = CONST.refstack_defcore_list
-        self.confpath = os.path.join(self.FUNCTEST_TEST,
-                                     self.CONF_PATH)
-        self.defcorelist = os.path.join(self.FUNCTEST_TEST,
-                                        self.DEFCORE_LIST)
-
-    def source_venv(self):
-
-        cmd = ("cd {0};"
-               ". .venv/bin/activate;"
-               "cd -;".format(CONST.dir_refstack_client))
-        ft_utils.execute_command(cmd)
+        self.tempestconf = None
+        self.conf_path = pkg_resources.resource_filename(
+            'functest',
+            'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
+        self.functest_test = pkg_resources.resource_filename(
+            'functest', 'opnfv_tests')
+        self.defcore_list = 'openstack/refstack_client/defcore.txt'
+        self.confpath = os.path.join(self.functest_test,
+                                     self.conf_path)
+        self.defcorelist = pkg_resources.resource_filename(
+            'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
+        self.testlist = None
+        self.insecure = ''
+        if ('https' in CONST.__getattribute__('OS_AUTH_URL') and
+                CONST.__getattribute__('OS_INSECURE').lower() == 'true'):
+            self.insecure = '-k'
+
+    def generate_conf(self):
+        if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR):
+            os.makedirs(conf_utils.REFSTACK_RESULTS_DIR)
 
-    def run_defcore(self, conf, testlist):
-        logger.debug("Generating test case list...")
+        self.tempestconf = TempestConf()
+        self.tempestconf.generate_tempestconf()
 
-        cmd = ("cd {0};"
-               "./refstack-client test -c {1} -v --test-list {2};"
-               "cd -;".format(CONST.dir_refstack_client,
-                              conf,
-                              testlist))
+    def run_defcore(self, conf, testlist):
+        """Run defcore sys command."""
+        cmd = ("refstack-client test {0} -c {1} -v --test-list {2}"
+               .format(self.insecure, conf, testlist))
+        LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd)
         ft_utils.execute_command(cmd)
 
     def run_defcore_default(self):
-        logger.debug("Generating test case list...")
-
-        cmd = ("cd {0};"
-               "./refstack-client test -c {1} -v --test-list {2};"
-               "cd -;".format(CONST.dir_refstack_client,
-                              self.confpath,
-                              self.defcorelist))
-        logger.info("Starting Refstack_defcore test case: '%s'." % cmd)
-
-        header = ("Refstack environment:\n"
-                  "  SUT: %s\n  Scenario: %s\n  Node: %s\n  Date: %s\n" %
-                  (CONST.INSTALLER_TYPE,
-                   CONST.DEPLOY_SCENARIO,
-                   CONST.NODE_NAME,
-                   time.strftime("%a %b %d %H:%M:%S %Z %Y")))
-
-        f_stdout = open(
-            os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
-                         "refstack.log"), 'w+')
-        f_env = open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
-                                  "environment.log"), 'w+')
-        f_env.write(header)
-
-        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
-                             stderr=subprocess.STDOUT, bufsize=1)
-
-        with p.stdout:
-            for line in iter(p.stdout.readline, b''):
-                if 'Tests' in line:
-                    break
-                if re.search("\} tempest\.", line):
-                    logger.info(line.replace('\n', ''))
-                f_stdout.write(line)
-        p.wait()
-
-        f_stdout.close()
-        f_env.close()
+        """Run default defcore sys command."""
+        options = ["-v"] if not self.insecure else ["-v", self.insecure]
+        cmd = (["refstack-client", "test", "-c", self.confpath] +
+               options + ["--test-list", self.defcorelist])
+        LOGGER.info("Starting Refstack_defcore test case: '%s'.", cmd)
+
+        with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+                               "environment.log"), 'w+') as f_env:
+            f_env.write(
+                ("Refstack environment:\n"
+                 "  SUT: {}\n  Scenario: {}\n  Node: {}\n  Date: {}\n").format(
+                    CONST.__getattribute__('INSTALLER_TYPE'),
+                    CONST.__getattribute__('DEPLOY_SCENARIO'),
+                    CONST.__getattribute__('NODE_NAME'),
+                    time.strftime("%a %b %d %H:%M:%S %Z %Y")))
+
+        with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+                               "refstack.log"), 'w+') as f_stdout:
+            subprocess.call(cmd, shell=False, stdout=f_stdout,
+                            stderr=subprocess.STDOUT)
 
     def parse_refstack_result(self):
+        """Parse Refstack results."""
         try:
+            with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+                                   "refstack.log"), 'r') as logfile:
+                for line in logfile.readlines():
+                    if 'Tests' in line:
+                        break
+                    if re.search(r"\} tempest\.", line):
+                        LOGGER.info(line.replace('\n', ''))
+
             with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
                                    "refstack.log"), 'r') as logfile:
                 output = logfile.read()
 
-            for match in re.findall("Ran: (\d+) tests in (\d+\.\d{4}) sec.",
+            for match in re.findall(r"Ran: (\d+) tests in (\d+\.\d{4}) sec.",
                                     output):
                 num_tests = match[0]
-                logger.info("Ran: %s tests in %s sec." % (num_tests, match[1]))
-            for match in re.findall("(- Passed: )(\d+)", output):
+                LOGGER.info("Ran: %s tests in %s sec.", num_tests, match[1])
+            for match in re.findall(r"(- Passed: )(\d+)", output):
                 num_success = match[1]
-                logger.info("".join(match))
-            for match in re.findall("(- Skipped: )(\d+)", output):
+                LOGGER.info("".join(match))
+            for match in re.findall(r"(- Skipped: )(\d+)", output):
                 num_skipped = match[1]
-                logger.info("".join(match))
-            for match in re.findall("(- Failed: )(\d+)", output):
+                LOGGER.info("".join(match))
+            for match in re.findall(r"(- Failed: )(\d+)", output):
                 num_failures = match[1]
-                logger.info("".join(match))
-            success_testcases = ""
-            for match in re.findall(r"\{0\}(.*?)[. ]*ok", output):
-                success_testcases += match + ", "
-            failed_testcases = ""
-            for match in re.findall(r"\{0\}(.*?)[. ]*FAILED", output):
-                failed_testcases += match + ", "
-            skipped_testcases = ""
-            for match in re.findall(r"\{0\}(.*?)[. ]*SKIPPED:", output):
-                skipped_testcases += match + ", "
+                LOGGER.info("".join(match))
+            success_testcases = []
+            for match in re.findall(r"\{0\} (.*?)[. ]*ok", output):
+                success_testcases.append(match)
+            failed_testcases = []
+            for match in re.findall(r"\{0\} (.*?)[. ]*FAILED", output):
+                failed_testcases.append(match)
+            skipped_testcases = []
+            for match in re.findall(r"\{0\} (.*?)[. ]*SKIPPED:", output):
+                skipped_testcases.append(match)
 
             num_executed = int(num_tests) - int(num_skipped)
 
             try:
                 self.result = 100 * int(num_success) / int(num_executed)
             except ZeroDivisionError:
-                logger.error("No test has been executed")
+                LOGGER.error("No test has been executed")
 
             self.details = {"tests": int(num_tests),
                             "failures": int(num_failures),
@@ -141,74 +150,86 @@ class RefstackClient(testcase.TestCase):
         except Exception:
             self.result = 0
 
-        logger.info("Testcase %s success_rate is %s%%"
-                    % (self.case_name, self.result))
+        LOGGER.info("Testcase %s success_rate is %s%%",
+                    self.case_name, self.result)
 
-    def run(self):
-        '''used for functest command line,
-           functest testcase run refstack_defcore'''
-        self.start_time = time.time()
+    @energy.enable_recording
+    def run(self, **kwargs):
+        """
+        Start RefstackClient testcase.
 
-        if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR):
-            os.makedirs(conf_utils.REFSTACK_RESULTS_DIR)
+        used for functest command line,
+        functest testcase run refstack_defcore
+        """
+        self.start_time = time.time()
 
         try:
-            tempestconf = TempestConf()
-            tempestconf.generate_tempestconf()
-            self.source_venv()
+            # Make sure that Tempest is configured
+            if not self.tempestconf:
+                self.generate_conf()
             self.run_defcore_default()
             self.parse_refstack_result()
             res = testcase.TestCase.EX_OK
-        except Exception as e:
-            logger.error('Error with run: %s', e)
+        except Exception:
+            LOGGER.exception("Error with run")
             res = testcase.TestCase.EX_RUN_ERROR
+        finally:
+            self.tempestconf.clean()
 
         self.stop_time = time.time()
         return res
 
     def _prep_test(self):
-        '''Check that the config file exists.'''
+        """Check that the config file exists."""
         if not os.path.isfile(self.confpath):
-            logger.error("Conf file not valid: %s" % self.confpath)
+            LOGGER.error("Conf file not valid: %s", self.confpath)
         if not os.path.isfile(self.testlist):
-            logger.error("testlist file not valid: %s" % self.testlist)
+            LOGGER.error("testlist file not valid: %s", self.testlist)
 
     def main(self, **kwargs):
-        '''used for manually running,
+        """
+        Execute RefstackClient testcase manually.
+
+        used for manually running,
            python refstack_client.py -c <tempest_conf_path>
            --testlist <testlist_path>
            can generate a reference refstack_tempest.conf by
            python tempest_conf.py
-        '''
+        """
         try:
             self.confpath = kwargs['config']
             self.testlist = kwargs['testlist']
-        except KeyError as e:
-            logger.error("Cannot run refstack client. Please check "
-                         "%s", e)
+        except KeyError as exc:
+            LOGGER.error("Cannot run refstack client. Please check "
+                         "%s", exc)
             return self.EX_RUN_ERROR
         try:
-            self.source_venv()
             self._prep_test()
             self.run_defcore(self.confpath, self.testlist)
             res = testcase.TestCase.EX_OK
-        except Exception as e:
-            logger.error('Error with run: %s', e)
+        except Exception as exc:
+            LOGGER.error('Error with run: %s', exc)
             res = testcase.TestCase.EX_RUN_ERROR
 
         return res
 
 
-class RefstackClientParser(object):
+class RefstackClientParser(object):  # pylint: disable=too-few-public-methods
+    """Command line argument parser helper."""
 
     def __init__(self):
-        self.FUNCTEST_TEST = CONST.dir_functest_test
-        self.CONF_PATH = CONST.refstack_tempest_conf_path
-        self.DEFCORE_LIST = CONST.refstack_defcore_list
-        self.confpath = os.path.join(self.FUNCTEST_TEST,
-                                     self.CONF_PATH)
-        self.defcorelist = os.path.join(self.FUNCTEST_TEST,
-                                        self.DEFCORE_LIST)
+        """Initialize helper object."""
+        self.functest_test = pkg_resources.resource_filename(
+            'functest', 'opnfv_tests')
+        self.conf_path = pkg_resources.resource_filename(
+            'functest',
+            'opnfv_tests/openstack/refstack_client/refstack_tempest.conf')
+        self.defcore_list = pkg_resources.resource_filename(
+            'functest', 'opnfv_tests/openstack/refstack_client/defcore.txt')
+        self.confpath = os.path.join(self.functest_test,
+                                     self.conf_path)
+        self.defcorelist = os.path.join(self.functest_test,
+                                        self.defcore_list)
         self.parser = argparse.ArgumentParser()
         self.parser.add_argument(
             '-c', '--config',
@@ -221,11 +242,13 @@ class RefstackClientParser(object):
                  'should be tested.',
             default=self.defcorelist)
 
-    def parse_args(self, argv=[]):
+    def parse_args(self, argv=None):
+        """Parse command line arguments."""
         return vars(self.parser.parse_args(argv))
 
 
-if __name__ == '__main__':
+def main():
+    """Run RefstackClient testcase with CLI."""
     logging.basicConfig()
     refstackclient = RefstackClient()
     parser = RefstackClientParser()
@@ -233,6 +256,6 @@ if __name__ == '__main__':
     try:
         result = refstackclient.main(**args)
         if result != testcase.TestCase.EX_OK:
-            sys.exit(result)
+            return result
     except Exception:
-        sys.exit(testcase.TestCase.EX_RUN_ERROR)
+        return testcase.TestCase.EX_RUN_ERROR