Currently the exception is not logged using the logger meaning that the only indication of the failure is the "module not loaded" error message. Catching the exception to log it the proper way will help identifying the cause of the issue, mainly for uninstall tests. closes odoo/odoo#100431 X-original-commit: b16f850d9aa438aea91b8cbd7c33692e1e1b2f90 Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
175 lines
6.3 KiB
Python
Executable File
175 lines
6.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import argparse
|
|
import logging
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
|
|
sys.path.append(os.path.abspath(os.path.join(__file__,'../../../')))
|
|
|
|
import odoo
|
|
from odoo.tools import config, topological_sort, unique
|
|
from odoo.netsvc import init_logger
|
|
from odoo.tests import standalone_tests
|
|
import odoo.tests.loader
|
|
|
|
_logger = logging.getLogger('odoo.tests.test_module_operations')
|
|
|
|
BLACKLIST = {
|
|
'auth_ldap', 'document_ftp', 'website_instantclick', 'pad',
|
|
'pad_project', 'note_pad', 'pos_cache', 'pos_blackbox_be',
|
|
}
|
|
IGNORE = ('hw_', 'theme_', 'l10n_', 'test_', 'payment_')
|
|
|
|
|
|
def install(db_name, module_id, module_name):
|
|
with odoo.registry(db_name).cursor() as cr:
|
|
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
|
module = env['ir.module.module'].browse(module_id)
|
|
module.button_immediate_install()
|
|
_logger.info('%s installed', module_name)
|
|
|
|
|
|
def uninstall(db_name, module_id, module_name):
|
|
with odoo.registry(db_name).cursor() as cr:
|
|
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
|
module = env['ir.module.module'].browse(module_id)
|
|
module.button_immediate_uninstall()
|
|
_logger.info('%s uninstalled', module_name)
|
|
|
|
|
|
def cycle(db_name, module_id, module_name):
|
|
install(db_name, module_id, module_name)
|
|
uninstall(db_name, module_id, module_name)
|
|
install(db_name, module_id, module_name)
|
|
|
|
|
|
class CheckAddons(argparse.Action):
|
|
def __call__(self, parser, namespace, values, option_string=None):
|
|
self.values = namespace
|
|
config._check_addons_path(self, option_string, values, self)
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(
|
|
description="Script for testing the install / uninstall / reinstall cycle of Odoo modules")
|
|
parser.add_argument("--database", "-d", type=str, required=True,
|
|
help="The database to test (note: must have only 'base' installed)")
|
|
parser.add_argument("--data-dir", "-D", dest="data_dir", type=str,
|
|
help="Directory where to store Odoo data"
|
|
)
|
|
parser.add_argument("--skip", "-s", type=str,
|
|
help="Comma-separated list of modules to skip (they will only be installed)")
|
|
parser.add_argument("--resume-at", "-r", type=str,
|
|
help="Skip modules (only install) up to the specified one in topological order")
|
|
parser.add_argument("--addons-path", "-p", type=str, action=CheckAddons,
|
|
help="Comma-separated list of paths to directories containing extra Odoo modules")
|
|
parser.add_argument("--uninstall", "-U", type=str,
|
|
help="Comma-separated list of modules to uninstall/reinstall")
|
|
parser.add_argument("--standalone", type=str,
|
|
help="Launch standalone scripts tagged with @standalone. Accepts a list of "
|
|
"module names or tags separated by commas. 'all' will run all available scripts."
|
|
)
|
|
return parser.parse_args()
|
|
|
|
|
|
def test_full(args):
|
|
""" Test full install/uninstall/reinstall cycle for all modules """
|
|
with odoo.registry(args.database).cursor() as cr:
|
|
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
|
|
|
def valid(module):
|
|
return not (
|
|
module.name in BLACKLIST
|
|
or module.name.startswith(IGNORE)
|
|
or module.state in ('installed', 'uninstallable')
|
|
)
|
|
|
|
modules = env['ir.module.module'].search([]).filtered(valid)
|
|
|
|
# order modules in topological order
|
|
modules = modules.browse(topological_sort({
|
|
module.id: module.dependencies_id.depend_id.ids
|
|
for module in modules
|
|
}))
|
|
modules_todo = [(module.id, module.name) for module in modules]
|
|
|
|
resume = args.resume_at
|
|
skip = set(args.skip.split(',')) if args.skip else set()
|
|
for module_id, module_name in modules_todo:
|
|
if module_name == resume:
|
|
resume = None
|
|
|
|
if resume or module_name in skip:
|
|
install(args.database, module_id, module_name)
|
|
else:
|
|
cycle(args.database, module_id, module_name)
|
|
|
|
|
|
def test_uninstall(args):
|
|
""" Tries to uninstall/reinstall one ore more modules"""
|
|
domain = [('name', 'in', args.uninstall.split(',')), ('state', '=', 'installed')]
|
|
with odoo.registry(args.database).cursor() as cr:
|
|
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
|
modules = env['ir.module.module'].search(domain)
|
|
modules_todo = [(module.id, module.name) for module in modules]
|
|
|
|
for module_id, module_name in modules_todo:
|
|
uninstall(args.database, module_id, module_name)
|
|
install(args.database, module_id, module_name)
|
|
|
|
|
|
def test_scripts(args):
|
|
""" Tries to launch standalone scripts tagged with @post_testing """
|
|
# load the registry once for script discovery
|
|
registry = odoo.registry(args.database)
|
|
for module_name in registry._init_modules:
|
|
# import tests for loaded modules
|
|
odoo.tests.loader.get_test_modules(module_name)
|
|
|
|
# fetch and filter scripts to test
|
|
funcs = list(unique(
|
|
func
|
|
for tag in args.standalone.split(',')
|
|
for func in standalone_tests[tag]
|
|
))
|
|
|
|
start_time = time.time()
|
|
for index, func in enumerate(funcs, start=1):
|
|
with odoo.registry(args.database).cursor() as cr:
|
|
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
|
|
_logger.info("Executing standalone script: %s (%d / %d)",
|
|
func.__name__, index, len(funcs))
|
|
try:
|
|
func(env)
|
|
except Exception:
|
|
_logger.error("Standalone script %s failed", func.__name__, exc_info=True)
|
|
|
|
_logger.info("%d standalone scripts executed in %.2fs" % (len(funcs), time.time() - start_time))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
args = parse_args()
|
|
|
|
# handle paths option
|
|
if args.addons_path:
|
|
odoo.tools.config['addons_path'] = ','.join([args.addons_path, odoo.tools.config['addons_path']])
|
|
if args.data_dir:
|
|
odoo.tools.config['data_dir'] = args.data_dir
|
|
odoo.modules.module.initialize_sys_path()
|
|
|
|
init_logger()
|
|
logging.getLogger('odoo.modules.loading').setLevel(logging.CRITICAL)
|
|
logging.getLogger('odoo.sql_db').setLevel(logging.CRITICAL)
|
|
|
|
try:
|
|
if args.uninstall:
|
|
test_uninstall(args)
|
|
elif args.standalone:
|
|
test_scripts(args)
|
|
else:
|
|
test_full(args)
|
|
except Exception as e:
|
|
_logger.exception("An error occured during standalone tests: %s", e)
|