diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index ffc11018949..3536cf60db4 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -50,6 +50,7 @@ import openerp.pooler as pooler import openerp.release as release import openerp.tools as tools import openerp.tools.osutil as osutil +import openerp.tools.assertion_report as assertion_report from openerp.tools.safe_eval import safe_eval as eval from openerp.tools.translate import _ @@ -97,9 +98,11 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= try: threading.currentThread().testing = True _load_data(cr, module_name, idref, mode, 'test') + return True except Exception, e: - _logger.exception( - 'Tests failed to execute in module %s', module_name) + _logger.error( + 'module %s: an exception occured in a test', module_name) + return False finally: threading.currentThread().testing = False if tools.config.options['test_commit']: @@ -132,7 +135,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= elif ext == '.sql': process_sql_file(cr, fp) elif ext == '.yml': - tools.convert_yaml_import(cr, module_name, fp, idref, mode, noupdate) + tools.convert_yaml_import(cr, module_name, fp, idref, mode, noupdate, report) else: tools.convert_xml_import(cr, module_name, fp, idref, mode, noupdate, report) finally: @@ -201,13 +204,13 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules= # 'data' section, but should probably not alter the data, # as there is no rollback. if tools.config.options['test_enable']: - load_test(module_name, idref, mode) + report.record_result(load_test(module_name, idref, mode)) # Run the `fast_suite` and `checks` tests given by the module. if module_name == 'base': - # Also run the core tests after the dabase is created. - openerp.modules.module.run_unit_tests('openerp') - openerp.modules.module.run_unit_tests(module_name) + # Also run the core tests after the database is created. + report.record_result(openerp.modules.module.run_unit_tests('openerp')) + report.record_result(openerp.modules.module.run_unit_tests(module_name)) processed_modules.append(package.name) @@ -288,7 +291,6 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # This is a brand new pool, just created in pooler.get_db_and_pool() pool = pooler.get_pool(cr.dbname) - report = tools.assertion_report() if 'base' in tools.config['update'] or 'all' in tools.config['update']: cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed')) @@ -301,6 +303,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): # processed_modules: for cleanup step after install # loaded_modules: to avoid double loading + report = assertion_report.assertion_report() loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=(not update_module), report=report) if tools.config['load_language']: @@ -420,7 +423,10 @@ def load_modules(db, force_demo=False, status=None, update_module=False): cr.execute("update ir_module_module set state=%s where state=%s", ('uninstalled', 'to remove',)) cr.commit() - _logger.info('Modules loaded.') + if report.failures: + _logger.error('At least one test failed when loading the modules.') + else: + _logger.info('Modules loaded.') finally: cr.close() diff --git a/openerp/modules/module.py b/openerp/modules/module.py index 3818882aab6..d1f6912bd29 100644 --- a/openerp/modules/module.py +++ b/openerp/modules/module.py @@ -549,6 +549,10 @@ def get_test_modules(module, submodule, explode): return ms def run_unit_tests(module_name): + """ + Return True or False if some tests were found and succeeded or failed. + Return None if no test was found. + """ import unittest2 ms = get_test_modules(module_name, '__fast_suite__', explode=False) ms.extend(get_test_modules(module_name, '__sanity_checks__', explode=False)) @@ -573,7 +577,10 @@ def run_unit_tests(module_name): first = False _logger.log(logging.TEST, c) result = unittest2.TextTestRunner(verbosity=2, stream=MyStream()).run(suite) - if not result.wasSuccessful(): + if result.wasSuccessful(): + return True + else: _logger.error('module %s: at least one error occured in a test', module_name) + return False # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/openerp/tools/assertion_report.py b/openerp/tools/assertion_report.py new file mode 100644 index 00000000000..60606d10d9c --- /dev/null +++ b/openerp/tools/assertion_report.py @@ -0,0 +1,29 @@ + +class assertion_report(object): + """ + Simple pair of success and failures counts (used to record YAML and XML + `assert` tags as well as unittest2 tests outcome (in this case, not + individual `assert`)). + """ + def __init__(self): + self.successes = 0 + self.failures = 0 + + def record_success(self): + self.successes += 1 + + def record_failure(self): + self.failures += 1 + + def record_result(self, result): + if result is None: + pass + elif result is True: + self.record_success() + elif result is False: + self.record_failure() + + def __str__(self): + res = 'Assertions report: %s successes, %s failures' % (self.successes, self.failures) + return res + diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index ec096a87218..0b1fd136c13 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -30,6 +30,8 @@ import re import time import openerp.release as release +import assertion_report + _logger = logging.getLogger(__name__) try: @@ -200,35 +202,6 @@ escape_re = re.compile(r'(?= config['assert_exit_level']: raise YamlImportAbortion('Severe assertion failure (%s), aborting.' % levelname) @@ -286,7 +263,7 @@ class YamlInterpreter(object): self._log_assert_failure(assertion.severity, msg, *args) return else: # all tests were successful for this assertion tag (no break) - self.assert_report.record(True, assertion.severity) + self.assertion_report.record_success() def _coerce_bool(self, value, default=False): if isinstance(value, types.BooleanType): @@ -534,7 +511,7 @@ class YamlInterpreter(object): _logger.debug('Exception during evaluation of !python block in yaml_file %s.', self.filename, exc_info=True) raise else: - self.assert_report.record(True, python.severity) + self.assertion_report.record_success() def process_workflow(self, node): workflow, values = node.items()[0] @@ -900,11 +877,11 @@ class YamlInterpreter(object): is_preceded_by_comment = False return is_preceded_by_comment -def yaml_import(cr, module, yamlfile, idref=None, mode='init', noupdate=False): +def yaml_import(cr, module, yamlfile, idref=None, mode='init', noupdate=False, report=None): if idref is None: idref = {} yaml_string = yamlfile.read() - yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, noupdate=noupdate) + yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, report=report, noupdate=noupdate) yaml_interpreter.process(yaml_string) # keeps convention of convert.py