]> git.llucax.com Git - software/mutest.git/blobdiff - py/mutest
Implement test suite initialization and termination
[software/mutest.git] / py / mutest
index 0c10bd788bd8b0442f457a22be149bff74520e24..8535523298b3379f2f0d3969e526766ae8405a18 100755 (executable)
--- a/py/mutest
+++ b/py/mutest
@@ -17,6 +17,10 @@ V_SUITE   = 3
 V_CASE    = 4
 V_CHECK   = 5
 
+R_OK      = 1
+R_FAILED  = 2
+R_SKIPPED = 3
+
 verbose_level = V_ERROR
 
 
@@ -37,6 +41,17 @@ def log(level, msg, *args):
                out.write((msg % args) + '\n')
 
 
+def get_fun(so, name, argtype=None, restype=None):
+       f = getattr(so, name)
+       f.argtypes = argtype
+       f.restype = restype
+       return f
+
+
+def get_val(so, name):
+       return c_int.in_dll(so, name).value
+
+
 #class SOError (Exception):
 #      pass
 
@@ -46,27 +61,18 @@ class TestCase(object):
        def __init__(self, so, name):
                self.so = so
                self.name = name
-               self.testcase = self.get_fun(name)
-               self.reset_counters = self.get_fun('mutest_reset_counters')
-               self.set_verbose_level = self.get_fun(
+               self.testcase = get_fun(so, name)
+               self.reset_counters = get_fun(so, 'mutest_reset_counters')
+               self.set_verbose_level = get_fun(so,
                                'mutest_set_verbose_level', argtype=[c_int])
 
        @property
        def passed_count(self):
-               return self.get_val('mutest_passed_count')
+               return get_val(self.so, 'mutest_passed_count')
 
        @property
        def failed_count(self):
-               return self.get_val('mutest_failed_count')
-
-       def get_fun(self, name, argtype=None, restype=None):
-               f = getattr(self.so, name)
-               f.argtypes = argtype
-               f.restype = restype
-               return f
-
-       def get_val(self, name):
-               return c_int.in_dll(self.so, name).value
+               return get_val(self.so, 'mutest_failed_count')
 
        def run(self):
                global verbose_level
@@ -76,8 +82,22 @@ class TestCase(object):
                return (self.passed_count, self.failed_count)
 
 
+class TestSuiteInfo (object):
+
+       inits_re = re.compile(r'[0-9a-f]{8} T (mu_init\w*)', re.I)
+       terms_re = re.compile(r'[0-9a-f]{8} T (mu_term\w*)', re.I)
+       cases_re = re.compile(r'[0-9a-f]{8} T (mu_test\w*)', re.I)
+
+       def __init__(self, so_name):
+               proc = Popen(['nm', '-p', so_name], stdout=PIPE)
+               output = proc.communicate()[0]
+               self.inits = self.inits_re.findall(output)
+               self.terms = self.terms_re.findall(output)
+               self.cases = self.cases_re.findall(output)
+
+
 class TestSuiteResult (object):
-       failed = False
+       result = R_OK
        passed_cases = 0
        failed_cases = 0
        passed_checks = 0
@@ -86,26 +106,43 @@ class TestSuiteResult (object):
        def __repr__(self):
                return 'TestSuiteResult(failed=%s, passed_cases=%s, '\
                        'failed_cases=%s, passed_checks=%s, failed_checks=%s)'\
-                               % (self.failed,
+                               % (self.result,
                                        self.passed_cases, self.failed_cases,
                                        self.passed_checks, self.failed_checks)
 
 
 class TestSuite (object):
 
-       def __init__(self, so, name, case_names):
+       def __init__(self, so, name, info):
                self.name = name
                self.so = so
                try:
-                       self.api_version = c_int.in_dll(self.so,
-                                       'mutest_api_version').value
+                       self.api_version = get_val(so, 'mutest_api_version')
                except ValueError:
                        self.api_version = 0
                        return
-               self.cases = [TestCase(self.so, name) for name in case_names]
+               self.inits = dict([(name, get_fun(so, name, restype=c_int))
+                               for name in info.inits])
+               self.terms = dict([(name, get_fun(so, name))
+                               for name in info.terms])
+               self.cases = [TestCase(self.so, name)
+                               for name in info.cases]
 
        def run(self):
                r = TestSuiteResult()
+
+               for name, func in self.inits.items():
+                       log(V_CASE, "\t+ Executing initialization function "
+                                       "'%s'...", name);
+                       res = func()
+                       if res:
+                               log(V_ERROR, "%s:%s: initialization function "
+                                               "failed (returned %d), "
+                                               "skipping test suite...\n",
+                                               self.name, name, res);
+                               r.result = R_SKIPPED
+                               return r
+
                for case in self.cases:
                        log(V_CASE, "\t* Executing test case '%s'...",
                                        case.name)
@@ -114,21 +151,19 @@ class TestSuite (object):
                                        'failed.', case_passed_checks,
                                        case_failed_checks)
                        if case_failed_checks:
-                               r.failed = True
+                               r.result = R_FAILED
                                r.failed_cases += 1
                        else:
                                r.passed_cases += 1
                        r.passed_checks += case_passed_checks
                        r.failed_checks += case_failed_checks
-               return r
-
 
-case_names_re = re.compile(r'[0-9a-f]{8} T (mu_test_\w+)', re.I)
+               for name, func in self.terms.items():
+                       log(V_CASE, "\t- Executing termination function "
+                                       "'%s'...", name)
+                       func()
 
-def get_case_names(so_name):
-       proc = Popen(['nm', '-p', so_name], stdout=PIPE)
-       output = proc.communicate()[0]
-       return case_names_re.findall(output)
+               return r
 
 
 def parse_arguments(args):
@@ -183,9 +218,9 @@ def main(args):
                        results['skipped_suites'] += 1
                        continue
 
-               case_names = get_case_names(so_name)
+               info = TestSuiteInfo(so_name)
 
-               suite = TestSuite(so, suite_name, case_names)
+               suite = TestSuite(so, suite_name, info)
 
                if suite.api_version != API_VERSION:
                        log(V_ERROR, 'Wrong API version (%s expected, %s '
@@ -202,8 +237,10 @@ def main(args):
                                r.passed_cases, r.failed_cases,
                                r.passed_checks, r.failed_checks)
 
-               if r.failed:
+               if r.result == R_FAILED:
                        results['failed_suites'] += 1
+               elif r.result == R_SKIPPED:
+                       results['skipped_suites'] += 1
                else:
                        results['passed_suites'] += 1
                results['failed_cases'] += r.failed_cases