Merge "Enable tempest multinode tests"
[functest.git] / functest / core / testcase.py
index 217f07e..a7dc47c 100644 (file)
 import logging
 import os
 
+import prettytable
+
 import functest.utils.functest_utils as ft_utils
+import functest.utils.openstack_clean as os_clean
+import functest.utils.openstack_snapshot as os_snapshot
 
 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
 
@@ -39,11 +43,46 @@ class TestCase(object):
         self.project_name = kwargs.get('project_name', 'functest')
         self.case_name = kwargs.get('case_name', '')
         self.criteria = kwargs.get('criteria', 100)
-        self.result = ""
-        self.start_time = ""
-        self.stop_time = ""
+        self.result = 0
+        self.start_time = 0
+        self.stop_time = 0
+
+    def __str__(self):
+        try:
+            assert self.project_name
+            assert self.case_name
+            result = 'PASS' if(self.is_successful(
+                ) == TestCase.EX_OK) else 'FAIL'
+            msg = prettytable.PrettyTable(
+                header_style='upper', padding_width=5,
+                field_names=['test case', 'project', 'duration',
+                             'result'])
+            msg.add_row([self.case_name, self.project_name,
+                         self.get_duration(), result])
+            return msg.get_string()
+        except AssertionError:
+            self.__logger.error("We cannot print invalid objects")
+            return super(TestCase, self).__str__()
+
+    def get_duration(self):
+        """Return the duration of the test case.
+
+        Returns:
+            duration if start_time and stop_time are set
+            "XX:XX" otherwise.
+        """
+        try:
+            assert self.start_time
+            assert self.stop_time
+            if self.stop_time < self.start_time:
+                return "XX:XX"
+            return "{0[0]:02.0f}:{0[1]:02.0f}".format(divmod(
+                self.stop_time - self.start_time, 60))
+        except Exception:  # pylint: disable=broad-except
+            self.__logger.error("Please run test before getting the duration")
+            return "XX:XX"
 
-    def check_result(self):
+    def is_successful(self):
         """Interpret the result of the test case.
 
         It allows getting the result of TestCase. It completes run()
@@ -57,7 +96,9 @@ class TestCase(object):
         """
         try:
             assert self.criteria
-            if isinstance(self.result, int) and isinstance(self.criteria, int):
+            assert self.result is not None
+            if (not isinstance(self.result, str) and
+                    not isinstance(self.criteria, str)):
                 if self.result >= self.criteria:
                     return TestCase.EX_OK
             else:
@@ -123,7 +164,7 @@ class TestCase(object):
             assert self.case_name
             assert self.start_time
             assert self.stop_time
-            pub_result = 'PASS' if self.check_result(
+            pub_result = 'PASS' if self.is_successful(
                 ) == TestCase.EX_OK else 'FAIL'
             if ft_utils.push_results_to_db(
                     self.project_name, self.case_name, self.start_time,
@@ -137,3 +178,51 @@ class TestCase(object):
         except Exception:  # pylint: disable=broad-except
             self.__logger.exception("The results cannot be pushed to DB")
             return TestCase.EX_PUSH_TO_DB_ERROR
+
+    def create_snapshot(self):  # pylint: disable=no-self-use
+        """Save the testing environment before running test.
+
+        It can be overriden if resources must be listed running the
+        test case.
+
+        Returns:
+            TestCase.EX_OK
+        """
+        return TestCase.EX_OK
+
+    def clean(self):
+        """Clean the resources.
+
+        It can be overriden if resources must be deleted after
+        running the test case.
+        """
+
+
+class OSGCTestCase(TestCase):
+    """Model for single test case which requires an OpenStack Garbage
+    Collector."""
+
+    __logger = logging.getLogger(__name__)
+
+    def create_snapshot(self):
+        """Create a snapshot listing the OpenStack resources.
+
+        Returns:
+            TestCase.EX_OK if os_snapshot.main() returns 0.
+            TestCase.EX_RUN_ERROR otherwise.
+        """
+        try:
+            assert os_snapshot.main() == 0
+            self.__logger.info("OpenStack resources snapshot created")
+            return TestCase.EX_OK
+        except Exception:  # pylint: disable=broad-except
+            self.__logger.exception("Cannot create the snapshot")
+            return TestCase.EX_RUN_ERROR
+
+    def clean(self):
+        """Clean the OpenStack resources."""
+        try:
+            assert os_clean.main() == 0
+            self.__logger.info("OpenStack resources cleaned")
+        except Exception:  # pylint: disable=broad-except
+            self.__logger.exception("Cannot clean the OpenStack resources")