write test results to a local file
authorwu.zhihui <wu.zhihui1@zte.com.cn>
Wed, 21 Dec 2016 01:49:19 +0000 (09:49 +0800)
committerwu.zhihui <wu.zhihui1@zte.com.cn>
Tue, 17 Jan 2017 06:33:24 +0000 (14:33 +0800)
Write test result to a file or push it to DB depends
on the value format of test_db_url which is defined in
config_functest.yaml. Meanwhile, test_db_url can be set
by os envrion value "RESULT_STORE".

If test_db_url is a url, e.g. http:// or https://, then
push result to DB. If test_db_url is a file location,
e.g. file:///, then write results to a file with json data.
One result record, one line.

JIRA: FUNCTEST-657

Change-Id: I579087cd2c24d61a79142b5d67003fb486b6c723
Signed-off-by: wu.zhihui <wu.zhihui1@zte.com.cn>
functest/ci/run_tests.py
functest/core/testcase_base.py
functest/opnfv_tests/openstack/vping/vping_base.py
functest/opnfv_tests/sdn/odl/odl.py
functest/tests/unit/core/test_testcase_base.py
functest/utils/functest_utils.py

index 35345fe..40d71db 100755 (executable)
@@ -146,7 +146,7 @@ def run_test(test, tier_name):
             result = test_case.run()
             if result == testcase_base.TestcaseBase.EX_OK:
                 if GlobalVariables.REPORT_FLAG:
-                    test_case.push_to_db()
+                    test_case.publish_report()
                 result = test_case.check_criteria()
         except ImportError:
             logger.exception("Cannot import module {}".format(
index 838b639..ec46bc6 100644 (file)
@@ -9,6 +9,7 @@
 
 import os
 
+from functest.utils.constants import CONST
 import functest.utils.functest_logger as ft_logger
 import functest.utils.functest_utils as ft_utils
 
@@ -17,7 +18,7 @@ class TestcaseBase(object):
 
     EX_OK = os.EX_OK
     EX_RUN_ERROR = os.EX_SOFTWARE
-    EX_PUSH_TO_DB_ERROR = os.EX_SOFTWARE - 1
+    EX_PUBLISH_RESULT_FAILED = os.EX_SOFTWARE - 1
     EX_TESTCASE_FAILED = os.EX_SOFTWARE - 2
 
     logger = ft_logger.Logger(__name__).getLogger()
@@ -43,21 +44,45 @@ class TestcaseBase(object):
         self.logger.error("Run must be implemented")
         return TestcaseBase.EX_RUN_ERROR
 
-    def push_to_db(self):
+    def publish_report(self):
+        if "RESULTS_STORE" in os.environ:
+            CONST.results_test_db_url = os.environ['RESULTS_STORE']
+
         try:
             assert self.project_name
             assert self.case_name
             assert self.criteria
             assert self.start_time
             assert self.stop_time
-            if ft_utils.push_results_to_db(
-                    self.project_name, self.case_name, self.start_time,
-                    self.stop_time, self.criteria, self.details):
-                self.logger.info("The results were successfully pushed to DB")
-                return TestcaseBase.EX_OK
+            if CONST.results_test_db_url.lower().startswith(
+                    ("http://", "https://")):
+                self.push_to_db()
+            elif CONST.results_test_db_url.lower().startswith("file://"):
+                self.write_to_file()
             else:
-                self.logger.error("The results cannot be pushed to DB")
-                return TestcaseBase.EX_PUSH_TO_DB_ERROR
+                self.logger.error("Please check parameter test_db_url and "
+                                  "OS environ variable RESTULTS_STORE")
+                return TestcaseBase.EX_PUBLISH_RESULT_FAILED
         except Exception:
-            self.logger.exception("The results cannot be pushed to DB")
-            return TestcaseBase.EX_PUSH_TO_DB_ERROR
+            self.logger.exception("The results cannot be stored")
+            return TestcaseBase.EX_PUBLISH_RESULT_FAILED
+
+    def write_to_file(self):
+        if ft_utils.write_results_to_file(
+                self.project_name, self.case_name, self.start_time,
+                self.stop_time, self.criteria, self.details):
+            self.logger.info("The results were successfully written to a file")
+            return TestcaseBase.EX_OK
+        else:
+            self.logger.error("write results to a file failed")
+            return TestcaseBase.EX_PUBLISH_RESULT_FAILED
+
+    def push_to_db(self):
+        if ft_utils.push_results_to_db(
+                self.project_name, self.case_name, self.start_time,
+                self.stop_time, self.criteria, self.details):
+            self.logger.info("The results were successfully pushed to DB")
+            return TestcaseBase.EX_OK
+        else:
+            self.logger.error("The results cannot be pushed to DB")
+            return TestcaseBase.EX_PUBLISH_RESULT_FAILED
index a5309bd..8285d93 100755 (executable)
@@ -289,6 +289,6 @@ class VPingMain(object):
             if result != VPingBase.EX_OK:
                 return result
             if kwargs['report']:
-                return self.vping.push_to_db()
+                return self.vping.publish_report()
         except Exception:
             return VPingBase.EX_RUN_ERROR
index 606d59a..50c3843 100755 (executable)
@@ -231,6 +231,6 @@ if __name__ == '__main__':
         if result != testcase_base.TestcaseBase.EX_OK:
             sys.exit(result)
         if args['pushtodb']:
-            sys.exit(odl.push_to_db())
+            sys.exit(odl.publish_report())
     except Exception:
         sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
index b6efa40..8df524b 100644 (file)
@@ -9,9 +9,11 @@
 
 import logging
 import mock
+import os
 import unittest
 
 mock.patch('logging.FileHandler').start()  # noqa
+
 from functest.core import testcase_base
 
 
@@ -32,11 +34,12 @@ class TestcaseBaseTesting(unittest.TestCase):
         self.assertEqual(self.test.run(),
                          testcase_base.TestcaseBase.EX_RUN_ERROR)
 
+    @mock.patch.dict(os.environ, {})
     @mock.patch('functest.utils.functest_utils.push_results_to_db',
                 return_value=False)
     def _test_missing_attribute(self, mock_function):
-        self.assertEqual(self.test.push_to_db(),
-                         testcase_base.TestcaseBase.EX_PUSH_TO_DB_ERROR)
+        self.assertEqual(self.test.publish_report(),
+                         testcase_base.TestcaseBase.EX_PUBLISH_RESULT_FAILED)
         mock_function.assert_not_called()
 
     def test_missing_case_name(self):
@@ -69,7 +72,7 @@ class TestcaseBaseTesting(unittest.TestCase):
                 return_value=False)
     def test_push_to_db_failed(self, mock_function):
         self.assertEqual(self.test.push_to_db(),
-                         testcase_base.TestcaseBase.EX_PUSH_TO_DB_ERROR)
+                         testcase_base.TestcaseBase.EX_PUBLISH_RESULT_FAILED)
         mock_function.assert_called_once_with(
             self.test.project, self.test.case_name, self.test.start_time,
             self.test.stop_time, self.test.criteria, self.test.details)
index 1879e69..2bf87a0 100644 (file)
@@ -23,8 +23,10 @@ import requests
 import yaml
 from git import Repo
 
+from functest.utils.constants import CONST
 import functest.utils.functest_logger as ft_logger
 
+
 logger = ft_logger.Logger("functest_utils").getLogger()
 
 
@@ -181,13 +183,43 @@ def logger_test_results(project, case_name, status, details):
             'd': details})
 
 
+def write_results_to_file(project, case_name, start_date,
+                          stop_date, criteria, details):
+    file_path = re.split(r'://', CONST.results_test_db_url)[1]
+
+    try:
+        installer = os.environ['INSTALLER_TYPE']
+        scenario = os.environ['DEPLOY_SCENARIO']
+        pod_name = os.environ['NODE_NAME']
+    except KeyError as e:
+        logger.error("Please set env var: " + str(e))
+        return False
+
+    test_start = dt.fromtimestamp(start_date).strftime('%Y-%m-%d %H:%M:%S')
+    test_stop = dt.fromtimestamp(stop_date).strftime('%Y-%m-%d %H:%M:%S')
+
+    params = {"project_name": project, "case_name": case_name,
+              "pod_name": pod_name, "installer": installer,
+              "scenario": scenario, "criteria": criteria,
+              "start_date": test_start, "stop_date": test_stop,
+              "details": details}
+    try:
+        with open(file_path, "a+w") as outfile:
+            json.dump(params, outfile)
+            outfile.write("\n")
+        return True
+    except Exception as e:
+        logger.error("write result data into a file failed: %s" % e)
+        return False
+
+
 def push_results_to_db(project, case_name,
                        start_date, stop_date, criteria, details):
     """
     POST results to the Result target DB
     """
     # Retrieve params from CI and conf
-    url = get_db_url() + "/results"
+    url = CONST.results_test_db_url + "/results"
 
     try:
         installer = os.environ['INSTALLER_TYPE']