diff --git a/database_cleanup/models/purge_modules.py b/database_cleanup/models/purge_modules.py index c099e390d..71f7eed82 100644 --- a/database_cleanup/models/purge_modules.py +++ b/database_cleanup/models/purge_modules.py @@ -72,6 +72,7 @@ class CleanupPurgeWizardModule(models.TransientModel): @api.model def find(self): res = [] + purge_lines = self.env['cleanup.purge.line.module'] IrModule = self.env['ir.module.module'] for module in IrModule.search( [ @@ -82,12 +83,14 @@ class CleanupPurgeWizardModule(models.TransientModel): if get_module_path(module.name, display_warning=False): continue if module.state == 'uninstalled': - self.env['cleanup.purge.line.module'].create({ + purge_lines += self.env['cleanup.purge.line.module'].create({ 'name': module.name, - }).purge() + }) continue res.append((0, 0, {'name': module.name})) + purge_lines.purge() + if not res: raise UserError(_('No modules found to purge')) return res diff --git a/database_cleanup/tests/test_database_cleanup.py b/database_cleanup/tests/test_database_cleanup.py index b05c804ea..d1d1c795c 100644 --- a/database_cleanup/tests/test_database_cleanup.py +++ b/database_cleanup/tests/test_database_cleanup.py @@ -1,5 +1,6 @@ # Copyright 2016 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from contextlib import contextmanager from psycopg2 import ProgrammingError from odoo.modules.registry import Registry from odoo.tools import config, mute_logger @@ -11,8 +12,8 @@ from odoo.tests.common import TransactionCase, tagged class TestDatabaseCleanup(TransactionCase): def setUp(self): super(TestDatabaseCleanup, self).setUp() - self.module = None - self.model = None + self.modules = self.env['ir.module.module'] + self.models = self.env['ir.model'] # Create one property for tests self.env['ir.property'].create({ 'fields_id': self.env.ref('base.field_res_partner__name').id, @@ -68,7 +69,7 @@ class TestDatabaseCleanup(TransactionCase): self.env.ref('database_cleanup.test_no_data_entry') # create a nonexistent model - self.model = self.env['ir.model'].create({ + self.models = self.env['ir.model'].create({ 'name': 'Database cleanup test model', 'model': 'x_database.cleanup.test.model', }) @@ -83,27 +84,6 @@ class TestDatabaseCleanup(TransactionCase): ('model', '=', 'x_database.cleanup.test.model'), ])) - # create a nonexistent module - self.module = self.env['ir.module.module'].create({ - 'name': 'database_cleanup_test', - 'state': 'to upgrade', - }) - purge_modules = self.env['cleanup.purge.wizard.module'].create({}) - # this reloads our registry, and we don't want to run tests twice - # we also need the original registry for further tests, so save a - # reference to it - original_registry = Registry.registries[self.env.cr.dbname] - config.options['test_enable'] = False - with mute_logger('odoo.modules.graph', 'odoo.modules.loading'): - purge_modules.purge_all() - config.options['test_enable'] = True - # must be removed by the wizard - self.assertFalse(self.env['ir.module.module'].search([ - ('name', '=', 'database_cleanup_test'), - ])) - # reset afterwards - Registry.registries[self.env.cr.dbname] = original_registry - # create an orphaned table self.env.cr.execute('create table database_cleanup_test (test int)') purge_tables = self.env['cleanup.purge.wizard.table'].create({}) @@ -113,17 +93,59 @@ class TestDatabaseCleanup(TransactionCase): with mute_logger('odoo.sql_db'): cr.execute('select * from database_cleanup_test') + def test_database_cleanup_modules(self): + + @contextmanager + def keep_registry(): + """purging a module resets the registry, so here we keep a + reference to our original registry, as we don't want to run tests + twice and need the original for further tests""" + original_registry = Registry.registries[self.env.cr.dbname] + config.options['test_enable'] = False + yield + config.options['test_enable'] = True + # reset afterwards + Registry.registries[self.env.cr.dbname] = original_registry + + # create nonexistent modules in different states + self.modules += self.env['ir.module.module'].create({ + 'name': 'database_cleanup_test_to_upgrade', + 'state': 'to upgrade', + }) + self.modules += self.env['ir.module.module'].create({ + 'name': 'database_cleanup_test_uninstalled', + 'state': 'uninstalled', + }) + + with keep_registry(), mute_logger( + 'odoo.modules.graph', 'odoo.modules.loading' + ): + purge_modules = self.env['cleanup.purge.wizard.module'].create({}) + # this module should be purged already during default_get + self.assertFalse(self.env['ir.module.module'].search([ + ('name', '=', 'database_cleanup_test_uninstalled'), + ])) + + with keep_registry(), mute_logger( + 'odoo.modules.graph', 'odoo.modules.loading' + ): + purge_modules.purge_all() + # must be removed by the wizard + self.assertFalse(self.env['ir.module.module'].search([ + ('name', '=', 'database_cleanup_test'), + ])) + def tearDown(self): super(TestDatabaseCleanup, self).tearDown() with self.registry.cursor() as cr2: # Release blocked tables with pending deletes self.env.cr.rollback() - if self.module: + if self.modules: cr2.execute( - "DELETE FROM ir_module_module WHERE id=%s", - (self.module.id,)) - if self.model: + "DELETE FROM ir_module_module WHERE id in %s", + (tuple(self.modules.ids),)) + if self.models: cr2.execute( - "DELETE FROM ir_model WHERE id=%s", - (self.model.id,)) + "DELETE FROM ir_model WHERE id in %s", + (tuple(self.models.ids),)) cr2.commit()