X-Git-Url: https://git.llucax.com/software/mutest.git/blobdiff_plain/78b63d329c2e3bb185c0b78119ccb5fc5c0781b9..75eb5c4a3edb32190187334ca9238b3b1ef2be39:/py/mutest diff --git a/py/mutest b/py/mutest index 0c10bd7..8535523 100755 --- 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