[IMP] module_auto_update: black, isort, prettier
parent
e93659fb03
commit
8592e0e285
|
@ -3,24 +3,20 @@
|
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
|
||||
{
|
||||
'name': 'Module Auto Update',
|
||||
'summary': 'Automatically update Odoo modules',
|
||||
'version': '12.0.2.0.5',
|
||||
'category': 'Extra Tools',
|
||||
'website': 'https://github.com/OCA/server-tools',
|
||||
'author': 'LasLabs, '
|
||||
'Juan José Scarafía, '
|
||||
'Tecnativa, '
|
||||
'ACSONE SA/NV, '
|
||||
'Odoo Community Association (OCA)',
|
||||
'license': 'LGPL-3',
|
||||
'installable': True,
|
||||
'uninstall_hook': 'uninstall_hook',
|
||||
'depends': [
|
||||
'base',
|
||||
],
|
||||
'data': [
|
||||
'views/ir_module_module.xml',
|
||||
],
|
||||
'development_status': 'Production/Stable',
|
||||
"name": "Module Auto Update",
|
||||
"summary": "Automatically update Odoo modules",
|
||||
"version": "12.0.2.0.5",
|
||||
"category": "Extra Tools",
|
||||
"website": "https://github.com/OCA/server-tools",
|
||||
"author": "LasLabs, "
|
||||
"Juan José Scarafía, "
|
||||
"Tecnativa, "
|
||||
"ACSONE SA/NV, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"license": "LGPL-3",
|
||||
"installable": True,
|
||||
"uninstall_hook": "uninstall_hook",
|
||||
"depends": ["base"],
|
||||
"data": ["views/ir_module_module.xml"],
|
||||
"development_status": "Production/Stable",
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# Copyright 2018 ACSONE SA/NV.
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
|
||||
from fnmatch import fnmatch
|
||||
import hashlib
|
||||
import os
|
||||
from fnmatch import fnmatch
|
||||
|
||||
|
||||
def _fnmatch(filename, patterns):
|
||||
|
@ -14,20 +14,20 @@ def _fnmatch(filename, patterns):
|
|||
|
||||
|
||||
def _walk(top, exclude_patterns, keep_langs):
|
||||
keep_langs = {l.split('_')[0] for l in keep_langs}
|
||||
keep_langs = {l.split("_")[0] for l in keep_langs}
|
||||
for dirpath, dirnames, filenames in os.walk(top):
|
||||
dirnames.sort()
|
||||
reldir = os.path.relpath(dirpath, top)
|
||||
if reldir == '.':
|
||||
reldir = ''
|
||||
if reldir == ".":
|
||||
reldir = ""
|
||||
for filename in sorted(filenames):
|
||||
filepath = os.path.join(reldir, filename)
|
||||
if _fnmatch(filepath, exclude_patterns):
|
||||
continue
|
||||
if keep_langs and reldir in {'i18n', 'i18n_extra'}:
|
||||
if keep_langs and reldir in {"i18n", "i18n_extra"}:
|
||||
basename, ext = os.path.splitext(filename)
|
||||
if ext == '.po':
|
||||
if basename.split('_')[0] not in keep_langs:
|
||||
if ext == ".po":
|
||||
if basename.split("_")[0] not in keep_langs:
|
||||
continue
|
||||
yield filepath
|
||||
|
||||
|
@ -37,8 +37,8 @@ def addon_hash(top, exclude_patterns, keep_langs):
|
|||
m = hashlib.sha1()
|
||||
for filepath in _walk(top, exclude_patterns, keep_langs):
|
||||
# hash filename so empty files influence the hash
|
||||
m.update(filepath.encode('utf-8'))
|
||||
m.update(filepath.encode("utf-8"))
|
||||
# hash file content
|
||||
with open(os.path.join(top, filepath), 'rb') as f:
|
||||
with open(os.path.join(top, filepath), "rb") as f:
|
||||
m.update(f.read())
|
||||
return m.hexdigest()
|
||||
|
|
|
@ -6,7 +6,5 @@ from openupgradelib import openupgrade
|
|||
@openupgrade.migrate()
|
||||
def migrate(env, version):
|
||||
openupgrade.delete_records_safely_by_xml_id(
|
||||
env, [
|
||||
'module_auto_update.module_check_upgrades_cron',
|
||||
],
|
||||
env, ["module_auto_update.module_check_upgrades_cron"],
|
||||
)
|
||||
|
|
|
@ -11,12 +11,9 @@ from odoo.modules.module import get_module_path
|
|||
|
||||
from ..addon_hash import addon_hash
|
||||
|
||||
PARAM_INSTALLED_CHECKSUMS = \
|
||||
'module_auto_update.installed_checksums'
|
||||
PARAM_EXCLUDE_PATTERNS = \
|
||||
'module_auto_update.exclude_patterns'
|
||||
DEFAULT_EXCLUDE_PATTERNS = \
|
||||
'*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*'
|
||||
PARAM_INSTALLED_CHECKSUMS = "module_auto_update.installed_checksums"
|
||||
PARAM_EXCLUDE_PATTERNS = "module_auto_update.exclude_patterns"
|
||||
DEFAULT_EXCLUDE_PATTERNS = "*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*"
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -34,40 +31,33 @@ def ensure_module_state(env, modules, state):
|
|||
if not modules:
|
||||
return
|
||||
env.cr.execute(
|
||||
"SELECT name FROM ir_module_module "
|
||||
"WHERE id IN %s AND state != %s",
|
||||
"SELECT name FROM ir_module_module " "WHERE id IN %s AND state != %s",
|
||||
(tuple(modules.ids), state),
|
||||
)
|
||||
names = [r[0] for r in env.cr.fetchall()]
|
||||
if names:
|
||||
raise FailedUpgradeError(
|
||||
"The following modules should be in state '%s' "
|
||||
"at this stage: %s. Bailing out for safety." %
|
||||
(state, ','.join(names), ),
|
||||
"at this stage: %s. Bailing out for safety." % (state, ",".join(names),),
|
||||
)
|
||||
|
||||
|
||||
class Module(models.Model):
|
||||
_inherit = 'ir.module.module'
|
||||
_inherit = "ir.module.module"
|
||||
|
||||
@api.multi
|
||||
def _get_checksum_dir(self):
|
||||
self.ensure_one()
|
||||
|
||||
exclude_patterns = self.env["ir.config_parameter"].get_param(
|
||||
PARAM_EXCLUDE_PATTERNS,
|
||||
DEFAULT_EXCLUDE_PATTERNS,
|
||||
PARAM_EXCLUDE_PATTERNS, DEFAULT_EXCLUDE_PATTERNS,
|
||||
)
|
||||
exclude_patterns = [p.strip() for p in exclude_patterns.split(',')]
|
||||
keep_langs = self.env['res.lang'].search([]).mapped('code')
|
||||
exclude_patterns = [p.strip() for p in exclude_patterns.split(",")]
|
||||
keep_langs = self.env["res.lang"].search([]).mapped("code")
|
||||
|
||||
module_path = get_module_path(self.name)
|
||||
if module_path and os.path.isdir(module_path):
|
||||
checksum_dir = addon_hash(
|
||||
module_path,
|
||||
exclude_patterns,
|
||||
keep_langs,
|
||||
)
|
||||
checksum_dir = addon_hash(module_path, exclude_patterns, keep_langs,)
|
||||
else:
|
||||
checksum_dir = False
|
||||
|
||||
|
@ -75,32 +65,30 @@ class Module(models.Model):
|
|||
|
||||
@api.model
|
||||
def _get_saved_checksums(self):
|
||||
Icp = self.env['ir.config_parameter']
|
||||
return json.loads(Icp.get_param(PARAM_INSTALLED_CHECKSUMS, '{}'))
|
||||
Icp = self.env["ir.config_parameter"]
|
||||
return json.loads(Icp.get_param(PARAM_INSTALLED_CHECKSUMS, "{}"))
|
||||
|
||||
@api.model
|
||||
def _save_checksums(self, checksums):
|
||||
Icp = self.env['ir.config_parameter']
|
||||
Icp = self.env["ir.config_parameter"]
|
||||
Icp.set_param(PARAM_INSTALLED_CHECKSUMS, json.dumps(checksums))
|
||||
|
||||
@api.model
|
||||
def _save_installed_checksums(self):
|
||||
checksums = {}
|
||||
installed_modules = self.search([('state', '=', 'installed')])
|
||||
installed_modules = self.search([("state", "=", "installed")])
|
||||
for module in installed_modules:
|
||||
checksums[module.name] = module._get_checksum_dir()
|
||||
self._save_checksums(checksums)
|
||||
|
||||
@api.model
|
||||
def _get_modules_partially_installed(self):
|
||||
return self.search([
|
||||
('state', 'in', ('to install', 'to remove', 'to upgrade')),
|
||||
])
|
||||
return self.search([("state", "in", ("to install", "to remove", "to upgrade"))])
|
||||
|
||||
@api.model
|
||||
def _get_modules_with_changed_checksum(self):
|
||||
saved_checksums = self._get_saved_checksums()
|
||||
installed_modules = self.search([('state', '=', 'installed')])
|
||||
installed_modules = self.search([("state", "=", "installed")])
|
||||
return installed_modules.filtered(
|
||||
lambda r: r._get_checksum_dir() != saved_checksums.get(r.name),
|
||||
)
|
||||
|
@ -131,32 +119,37 @@ class Module(models.Model):
|
|||
"""
|
||||
_logger.info(
|
||||
"Checksum upgrade starting (i18n-overwrite=%s)...",
|
||||
overwrite_existing_translations
|
||||
overwrite_existing_translations,
|
||||
)
|
||||
|
||||
tools.config['overwrite_existing_translations'] = \
|
||||
overwrite_existing_translations
|
||||
tools.config[
|
||||
"overwrite_existing_translations"
|
||||
] = overwrite_existing_translations
|
||||
|
||||
_logger.info("Updating modules list...")
|
||||
self.update_list()
|
||||
changed_modules = self._get_modules_with_changed_checksum()
|
||||
if not changed_modules and not self._get_modules_partially_installed():
|
||||
_logger.info("No checksum change detected in installed modules "
|
||||
"and all modules installed, nothing to do.")
|
||||
_logger.info(
|
||||
"No checksum change detected in installed modules "
|
||||
"and all modules installed, nothing to do."
|
||||
)
|
||||
return
|
||||
_logger.info("Marking the following modules to upgrade, "
|
||||
_logger.info(
|
||||
"Marking the following modules to upgrade, "
|
||||
"for their checksums changed: %s...",
|
||||
','.join(changed_modules.mapped('name')))
|
||||
",".join(changed_modules.mapped("name")),
|
||||
)
|
||||
changed_modules.button_upgrade()
|
||||
self.env.cr.commit() # pylint: disable=invalid-commit
|
||||
# in rare situations, button_upgrade may fail without
|
||||
# exception, this would lead to corruption because
|
||||
# no upgrade would be performed and save_installed_checksums
|
||||
# would update cheksums for modules that have not been upgraded
|
||||
ensure_module_state(self.env, changed_modules, 'to upgrade')
|
||||
ensure_module_state(self.env, changed_modules, "to upgrade")
|
||||
|
||||
_logger.info("Upgrading...")
|
||||
self.env['base.module.upgrade'].upgrade_module()
|
||||
self.env["base.module.upgrade"].upgrade_module()
|
||||
self.env.cr.commit() # pylint: disable=invalid-commit
|
||||
|
||||
_logger.info("Upgrade successful, updating checksums...")
|
||||
|
@ -167,8 +160,8 @@ class Module(models.Model):
|
|||
if partial_modules:
|
||||
raise IncompleteUpgradeError(
|
||||
"Checksum upgrade successful "
|
||||
"but incomplete for the following modules: %s" %
|
||||
','.join(partial_modules.mapped('name'))
|
||||
"but incomplete for the following modules: %s"
|
||||
% ",".join(partial_modules.mapped("name"))
|
||||
)
|
||||
|
||||
_logger.info("Checksum upgrade complete.")
|
||||
|
|
|
@ -1 +1 @@
|
|||
<odoo/>
|
||||
<odoo />
|
||||
|
|
|
@ -1 +1 @@
|
|||
<odoo/>
|
||||
<odoo />
|
||||
|
|
|
@ -1 +1 @@
|
|||
1+1
|
||||
_ = 1 + 1
|
||||
|
|
|
@ -9,59 +9,63 @@ from ..models.module import DEFAULT_EXCLUDE_PATTERNS
|
|||
|
||||
|
||||
class TestAddonHash(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAddonHash, self).setUp()
|
||||
self.sample_dir = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
'sample_module',
|
||||
)
|
||||
self.sample_dir = os.path.join(os.path.dirname(__file__), "sample_module",)
|
||||
|
||||
def test_basic(self):
|
||||
files = list(addon_hash._walk(
|
||||
self.sample_dir,
|
||||
exclude_patterns=["*/__pycache__/*"],
|
||||
keep_langs=[],
|
||||
))
|
||||
self.assertEqual(files, [
|
||||
'README.rst',
|
||||
'data/f1.xml',
|
||||
'data/f2.xml',
|
||||
'i18n/en.po',
|
||||
'i18n/en_US.po',
|
||||
'i18n/fr.po',
|
||||
'i18n/fr_BE.po',
|
||||
'i18n/test.pot',
|
||||
'i18n_extra/en.po',
|
||||
'i18n_extra/fr.po',
|
||||
'i18n_extra/nl_NL.po',
|
||||
'models/stuff.py',
|
||||
'models/stuff.pyc',
|
||||
'models/stuff.pyo',
|
||||
'static/src/some.js',
|
||||
])
|
||||
files = list(
|
||||
addon_hash._walk(
|
||||
self.sample_dir, exclude_patterns=["*/__pycache__/*"], keep_langs=[],
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
files,
|
||||
[
|
||||
"README.rst",
|
||||
"data/f1.xml",
|
||||
"data/f2.xml",
|
||||
"i18n/en.po",
|
||||
"i18n/en_US.po",
|
||||
"i18n/fr.po",
|
||||
"i18n/fr_BE.po",
|
||||
"i18n/test.pot",
|
||||
"i18n_extra/en.po",
|
||||
"i18n_extra/fr.po",
|
||||
"i18n_extra/nl_NL.po",
|
||||
"models/stuff.py",
|
||||
"models/stuff.pyc",
|
||||
"models/stuff.pyo",
|
||||
"static/src/some.js",
|
||||
],
|
||||
)
|
||||
|
||||
def test_exclude(self):
|
||||
files = list(addon_hash._walk(
|
||||
files = list(
|
||||
addon_hash._walk(
|
||||
self.sample_dir,
|
||||
exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(','),
|
||||
keep_langs=['fr_FR', 'nl'],
|
||||
))
|
||||
self.assertEqual(files, [
|
||||
'README.rst',
|
||||
'data/f1.xml',
|
||||
'data/f2.xml',
|
||||
'i18n/fr.po',
|
||||
'i18n/fr_BE.po',
|
||||
'i18n_extra/fr.po',
|
||||
'i18n_extra/nl_NL.po',
|
||||
'models/stuff.py',
|
||||
])
|
||||
exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(","),
|
||||
keep_langs=["fr_FR", "nl"],
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
files,
|
||||
[
|
||||
"README.rst",
|
||||
"data/f1.xml",
|
||||
"data/f2.xml",
|
||||
"i18n/fr.po",
|
||||
"i18n/fr_BE.po",
|
||||
"i18n_extra/fr.po",
|
||||
"i18n_extra/nl_NL.po",
|
||||
"models/stuff.py",
|
||||
],
|
||||
)
|
||||
|
||||
def test2(self):
|
||||
checksum = addon_hash.addon_hash(
|
||||
self.sample_dir,
|
||||
exclude_patterns=['*.pyc', '*.pyo', '*.pot', 'static/*'],
|
||||
keep_langs=['fr_FR', 'nl'],
|
||||
exclude_patterns=["*.pyc", "*.pyo", "*.pot", "static/*"],
|
||||
keep_langs=["fr_FR", "nl"],
|
||||
)
|
||||
self.assertEqual(checksum, 'fecb89486c8a29d1f760cbd01c1950f6e8421b14')
|
||||
self.assertEqual(checksum, "fecb89486c8a29d1f760cbd01c1950f6e8421b14")
|
||||
|
|
|
@ -12,23 +12,22 @@ from odoo.modules import get_module_path
|
|||
from odoo.tests import TransactionCase
|
||||
|
||||
from ..addon_hash import addon_hash
|
||||
from ..models.module import IncompleteUpgradeError, DEFAULT_EXCLUDE_PATTERNS
|
||||
from ..models.module import DEFAULT_EXCLUDE_PATTERNS, IncompleteUpgradeError
|
||||
|
||||
MODULE_NAME = 'module_auto_update'
|
||||
MODULE_NAME = "module_auto_update"
|
||||
|
||||
|
||||
class TestModule(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestModule, self).setUp()
|
||||
self.own_module = self.env['ir.module.module'].search([
|
||||
('name', '=', MODULE_NAME),
|
||||
])
|
||||
self.own_module = self.env["ir.module.module"].search(
|
||||
[("name", "=", MODULE_NAME)]
|
||||
)
|
||||
self.own_dir_path = get_module_path(MODULE_NAME)
|
||||
keep_langs = self.env['res.lang'].search([]).mapped('code')
|
||||
keep_langs = self.env["res.lang"].search([]).mapped("code")
|
||||
self.own_checksum = addon_hash(
|
||||
self.own_dir_path,
|
||||
exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(','),
|
||||
exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(","),
|
||||
keep_langs=keep_langs,
|
||||
)
|
||||
self.own_writeable = os.access(self.own_dir_path, os.W_OK)
|
||||
|
@ -36,8 +35,9 @@ class TestModule(TransactionCase):
|
|||
def test_compute_checksum_dir(self):
|
||||
"""It should compute the directory's SHA-1 hash"""
|
||||
self.assertEqual(
|
||||
self.own_module._get_checksum_dir(), self.own_checksum,
|
||||
'Module directory checksum not computed properly',
|
||||
self.own_module._get_checksum_dir(),
|
||||
self.own_checksum,
|
||||
"Module directory checksum not computed properly",
|
||||
)
|
||||
|
||||
def test_compute_checksum_dir_ignore_excluded(self):
|
||||
|
@ -45,10 +45,11 @@ class TestModule(TransactionCase):
|
|||
calculations"""
|
||||
if not self.own_writeable:
|
||||
self.skipTest("Own directory not writeable")
|
||||
with tempfile.NamedTemporaryFile(suffix='.pyc', dir=self.own_dir_path):
|
||||
with tempfile.NamedTemporaryFile(suffix=".pyc", dir=self.own_dir_path):
|
||||
self.assertEqual(
|
||||
self.own_module._get_checksum_dir(), self.own_checksum,
|
||||
'SHA1 checksum does not ignore excluded extensions',
|
||||
self.own_module._get_checksum_dir(),
|
||||
self.own_checksum,
|
||||
"SHA1 checksum does not ignore excluded extensions",
|
||||
)
|
||||
|
||||
def test_compute_checksum_dir_recomputes_when_file_added(self):
|
||||
|
@ -56,62 +57,59 @@ class TestModule(TransactionCase):
|
|||
added to the module directory"""
|
||||
if not self.own_writeable:
|
||||
self.skipTest("Own directory not writeable")
|
||||
with tempfile.NamedTemporaryFile(suffix='.py', dir=self.own_dir_path):
|
||||
with tempfile.NamedTemporaryFile(suffix=".py", dir=self.own_dir_path):
|
||||
self.assertNotEqual(
|
||||
self.own_module._get_checksum_dir(), self.own_checksum,
|
||||
'SHA1 checksum not recomputed',
|
||||
self.own_module._get_checksum_dir(),
|
||||
self.own_checksum,
|
||||
"SHA1 checksum not recomputed",
|
||||
)
|
||||
|
||||
def test_saved_checksums(self):
|
||||
Imm = self.env['ir.module.module']
|
||||
base_module = Imm.search([('name', '=', 'base')])
|
||||
self.assertEqual(base_module.state, 'installed')
|
||||
Imm = self.env["ir.module.module"]
|
||||
base_module = Imm.search([("name", "=", "base")])
|
||||
self.assertEqual(base_module.state, "installed")
|
||||
self.assertFalse(Imm._get_saved_checksums())
|
||||
Imm._save_installed_checksums()
|
||||
saved_checksums = Imm._get_saved_checksums()
|
||||
self.assertTrue(saved_checksums)
|
||||
self.assertTrue(saved_checksums['base'])
|
||||
self.assertTrue(saved_checksums["base"])
|
||||
|
||||
def test_get_modules_with_changed_checksum(self):
|
||||
Imm = self.env['ir.module.module']
|
||||
Imm = self.env["ir.module.module"]
|
||||
self.assertTrue(Imm._get_modules_with_changed_checksum())
|
||||
Imm._save_installed_checksums()
|
||||
self.assertFalse(Imm._get_modules_with_changed_checksum())
|
||||
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
@odoo.tests.tagged("post_install", "-at_install")
|
||||
class TestModuleAfterInstall(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestModuleAfterInstall, self).setUp()
|
||||
Imm = self.env['ir.module.module']
|
||||
self.own_module = Imm.search([('name', '=', MODULE_NAME)])
|
||||
self.base_module = Imm.search([('name', '=', 'base')])
|
||||
Imm = self.env["ir.module.module"]
|
||||
self.own_module = Imm.search([("name", "=", MODULE_NAME)])
|
||||
self.base_module = Imm.search([("name", "=", "base")])
|
||||
|
||||
def test_get_modules_partially_installed(self):
|
||||
Imm = self.env['ir.module.module']
|
||||
self.assertTrue(
|
||||
self.own_module not in Imm._get_modules_partially_installed())
|
||||
Imm = self.env["ir.module.module"]
|
||||
self.assertTrue(self.own_module not in Imm._get_modules_partially_installed())
|
||||
self.own_module.button_upgrade()
|
||||
self.assertTrue(
|
||||
self.own_module in Imm._get_modules_partially_installed())
|
||||
self.assertTrue(self.own_module in Imm._get_modules_partially_installed())
|
||||
self.own_module.button_upgrade_cancel()
|
||||
self.assertTrue(
|
||||
self.own_module not in Imm._get_modules_partially_installed())
|
||||
self.assertTrue(self.own_module not in Imm._get_modules_partially_installed())
|
||||
|
||||
def test_upgrade_changed_checksum(self):
|
||||
Imm = self.env['ir.module.module']
|
||||
Bmu = self.env['base.module.upgrade']
|
||||
Imm = self.env["ir.module.module"]
|
||||
Bmu = self.env["base.module.upgrade"]
|
||||
|
||||
# check modules are in installed state
|
||||
installed_modules = Imm.search([('state', '=', 'installed')])
|
||||
installed_modules = Imm.search([("state", "=", "installed")])
|
||||
self.assertTrue(self.own_module in installed_modules)
|
||||
self.assertTrue(self.base_module in installed_modules)
|
||||
self.assertTrue(len(installed_modules) > 2)
|
||||
# change the checksum of 'base'
|
||||
Imm._save_installed_checksums()
|
||||
saved_checksums = Imm._get_saved_checksums()
|
||||
saved_checksums['base'] = False
|
||||
saved_checksums["base"] = False
|
||||
Imm._save_checksums(saved_checksums)
|
||||
changed_modules = Imm._get_modules_with_changed_checksum()
|
||||
self.assertEqual(len(changed_modules), 1)
|
||||
|
@ -121,102 +119,100 @@ class TestModuleAfterInstall(TransactionCase):
|
|||
upgrade_module_mock.call_count += 1
|
||||
# since we are upgrading base, all installed module
|
||||
# must have been marked to upgrade at this stage
|
||||
self.assertEqual(self.base_module.state, 'to upgrade')
|
||||
self.assertEqual(self.own_module.state, 'to upgrade')
|
||||
installed_modules.write({'state': 'installed'})
|
||||
self.assertEqual(self.base_module.state, "to upgrade")
|
||||
self.assertEqual(self.own_module.state, "to upgrade")
|
||||
installed_modules.write({"state": "installed"})
|
||||
|
||||
upgrade_module_mock.call_count = 0
|
||||
|
||||
# upgrade_changed_checksum commits, so mock that
|
||||
with mock.patch.object(self.env.cr, 'commit'):
|
||||
with mock.patch.object(self.env.cr, "commit"):
|
||||
|
||||
# we simulate an install by setting module states
|
||||
Bmu._patch_method('upgrade_module', upgrade_module_mock)
|
||||
Bmu._patch_method("upgrade_module", upgrade_module_mock)
|
||||
try:
|
||||
Imm.upgrade_changed_checksum()
|
||||
self.assertEqual(upgrade_module_mock.call_count, 1)
|
||||
self.assertEqual(self.base_module.state, 'installed')
|
||||
self.assertEqual(self.own_module.state, 'installed')
|
||||
self.assertEqual(self.base_module.state, "installed")
|
||||
self.assertEqual(self.own_module.state, "installed")
|
||||
saved_checksums = Imm._get_saved_checksums()
|
||||
self.assertTrue(saved_checksums['base'])
|
||||
self.assertTrue(saved_checksums["base"])
|
||||
self.assertTrue(saved_checksums[MODULE_NAME])
|
||||
finally:
|
||||
Bmu._revert_method('upgrade_module')
|
||||
Bmu._revert_method("upgrade_module")
|
||||
|
||||
def test_incomplete_upgrade(self):
|
||||
Imm = self.env['ir.module.module']
|
||||
Bmu = self.env['base.module.upgrade']
|
||||
Imm = self.env["ir.module.module"]
|
||||
Bmu = self.env["base.module.upgrade"]
|
||||
|
||||
installed_modules = Imm.search([('state', '=', 'installed')])
|
||||
installed_modules = Imm.search([("state", "=", "installed")])
|
||||
# change the checksum of 'base'
|
||||
Imm._save_installed_checksums()
|
||||
saved_checksums = Imm._get_saved_checksums()
|
||||
saved_checksums['base'] = False
|
||||
saved_checksums["base"] = False
|
||||
Imm._save_checksums(saved_checksums)
|
||||
|
||||
def upgrade_module_mock(self_model):
|
||||
upgrade_module_mock.call_count += 1
|
||||
# since we are upgrading base, all installed module
|
||||
# must have been marked to upgrade at this stage
|
||||
self.assertEqual(self.base_module.state, 'to upgrade')
|
||||
self.assertEqual(self.own_module.state, 'to upgrade')
|
||||
installed_modules.write({'state': 'installed'})
|
||||
self.assertEqual(self.base_module.state, "to upgrade")
|
||||
self.assertEqual(self.own_module.state, "to upgrade")
|
||||
installed_modules.write({"state": "installed"})
|
||||
# simulate partial upgrade
|
||||
self.own_module.write({'state': 'to upgrade'})
|
||||
self.own_module.write({"state": "to upgrade"})
|
||||
|
||||
upgrade_module_mock.call_count = 0
|
||||
|
||||
# upgrade_changed_checksum commits, so mock that
|
||||
with mock.patch.object(self.env.cr, 'commit'):
|
||||
with mock.patch.object(self.env.cr, "commit"):
|
||||
|
||||
# we simulate an install by setting module states
|
||||
Bmu._patch_method('upgrade_module', upgrade_module_mock)
|
||||
Bmu._patch_method("upgrade_module", upgrade_module_mock)
|
||||
try:
|
||||
with self.assertRaises(IncompleteUpgradeError):
|
||||
Imm.upgrade_changed_checksum()
|
||||
self.assertEqual(upgrade_module_mock.call_count, 1)
|
||||
finally:
|
||||
Bmu._revert_method('upgrade_module')
|
||||
Bmu._revert_method("upgrade_module")
|
||||
|
||||
def test_incomplete_upgrade_no_checkusm(self):
|
||||
Imm = self.env['ir.module.module']
|
||||
Bmu = self.env['base.module.upgrade']
|
||||
Imm = self.env["ir.module.module"]
|
||||
Bmu = self.env["base.module.upgrade"]
|
||||
|
||||
installed_modules = Imm.search(
|
||||
[('state', '=', 'installed')])
|
||||
installed_modules = Imm.search([("state", "=", "installed")])
|
||||
# change the checksum of 'base'
|
||||
Imm._save_installed_checksums()
|
||||
saved_checksums = Imm._get_saved_checksums()
|
||||
|
||||
Imm._save_checksums(saved_checksums)
|
||||
self.base_module.write({'state': 'to upgrade'})
|
||||
self.base_module.write({"state": "to upgrade"})
|
||||
|
||||
def upgrade_module_mock(self_model):
|
||||
upgrade_module_mock.call_count += 1
|
||||
# since we are upgrading base, all installed module
|
||||
# must have been marked to upgrade at this stage
|
||||
self.assertEqual(self.base_module.state, 'to upgrade')
|
||||
self.assertEqual(self.own_module.state, 'installed')
|
||||
installed_modules.write({'state': 'installed'})
|
||||
self.assertEqual(self.base_module.state, "to upgrade")
|
||||
self.assertEqual(self.own_module.state, "installed")
|
||||
installed_modules.write({"state": "installed"})
|
||||
|
||||
upgrade_module_mock.call_count = 0
|
||||
|
||||
# upgrade_changed_checksum commits, so mock that
|
||||
with mock.patch.object(self.env.cr, 'commit'):
|
||||
with mock.patch.object(self.env.cr, "commit"):
|
||||
|
||||
# we simulate an install by setting module states
|
||||
Bmu._patch_method('upgrade_module',
|
||||
upgrade_module_mock)
|
||||
Bmu._patch_method("upgrade_module", upgrade_module_mock)
|
||||
# got just other modules to_upgrade and no checksum ones
|
||||
try:
|
||||
Imm.upgrade_changed_checksum()
|
||||
self.assertEqual(upgrade_module_mock.call_count, 1)
|
||||
finally:
|
||||
Bmu._revert_method('upgrade_module')
|
||||
Bmu._revert_method("upgrade_module")
|
||||
|
||||
def test_nothing_to_upgrade(self):
|
||||
Imm = self.env['ir.module.module']
|
||||
Bmu = self.env['base.module.upgrade']
|
||||
Imm = self.env["ir.module.module"]
|
||||
Bmu = self.env["base.module.upgrade"]
|
||||
|
||||
Imm._save_installed_checksums()
|
||||
|
||||
|
@ -226,12 +222,12 @@ class TestModuleAfterInstall(TransactionCase):
|
|||
upgrade_module_mock.call_count = 0
|
||||
|
||||
# upgrade_changed_checksum commits, so mock that
|
||||
with mock.patch.object(self.env.cr, 'commit'):
|
||||
with mock.patch.object(self.env.cr, "commit"):
|
||||
|
||||
# we simulate an install by setting module states
|
||||
Bmu._patch_method('upgrade_module', upgrade_module_mock)
|
||||
Bmu._patch_method("upgrade_module", upgrade_module_mock)
|
||||
try:
|
||||
Imm.upgrade_changed_checksum()
|
||||
self.assertEqual(upgrade_module_mock.call_count, 0)
|
||||
finally:
|
||||
Bmu._revert_method('upgrade_module')
|
||||
Bmu._revert_method("upgrade_module")
|
||||
|
|
|
@ -4,17 +4,15 @@
|
|||
Copyright 2018 Brainbean Apps (https://brainbeanapps.com)
|
||||
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
|
||||
-->
|
||||
|
||||
<record id="ir_module_module_upgrade_changed_checksum" model="ir.actions.server">
|
||||
<field name="name">Auto-Upgrade Modules</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="model_id" ref="base.model_ir_module_module"/>
|
||||
<field name="model_id" ref="base.model_ir_module_module" />
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
action = model.upgrade_changed_checksum()
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
name="Auto-Upgrade Modules"
|
||||
action="ir_module_module_upgrade_changed_checksum"
|
||||
|
@ -22,6 +20,6 @@
|
|||
groups="base.group_no_one"
|
||||
parent="base.menu_management"
|
||||
sequence="45"
|
||||
icon="fa-exchange"/>
|
||||
|
||||
icon="fa-exchange"
|
||||
/>
|
||||
</odoo>
|
||||
|
|
Loading…
Reference in New Issue