When an addon has an invalid version but is not installable,
there is no need to error out. This situation typically happens
when unmigrated modules are present in the addons path.
closesodoo/odoo#157657
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
-Step to reproduce: add a post_load method in the init of any module,
specify in the manifest like : 'post_load': 'post_load'. in v16 or above
Run
test_manifests of the test_lint module and we will get warning
closesodoo/odoo#156593
X-original-commit: f87473e82af8372346320ca747c1b41d3d5cf3c5
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Before this PR, after having imported a module, a warning appears in the
log, because it tries to update the graph which does not make sense for
an imported module.
This commit makes sure the warning is skipped if the module was
imported.
closesodoo/odoo#155096
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
Make the set() of module sorted, aka a list.
We can be pretty sure that nobody relied on the order of this set before
since it was completely underterministic. Therefor this change should
not break anything and make the testing on runbot more consistant.
This is mainly following the issue with the sql-injection testing
failing randomly with the order of the modules.
closesodoo/odoo#154324
X-original-commit: bbe33a1260ab3bfe97caa1197adbf00c661ddfb4
Signed-off-by: Vranckx Florian (flvr) <flvr@odoo.com>
do not compare types, for exact checks use `is` / `is not`,
for instance checks use `isinstance()`Flake8(E721)
Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
`field_computed` is decorated with `lazy_property` and will be reset by
`setup_models` If a request comes, read `field_compute` when `setup_models`
just clears some fields. The `field_compute` will be cached with fewer fields
and cause KeyError for the registry in the future.
This commit re-clear lazy_property for registry after fields are modified
X-original-commit: 04e35d7bf3ca98dc722795c75033747697d70d30
Part-of: odoo/odoo#146544
If `setup_models` is called concurrently,
the first one just delete the `registry._m2m`.
then the latter one tries to access `registry._m2m`.
An error 'Registry' object has no attribute '_m2m' will be raised
This commit add a lock to the `setup_model` to fix the problem
X-original-commit: 9ae78193f5c9ae4dcfa28c4ea4be1a7f98e42136
Part-of: odoo/odoo#146544
A custom script is modifying the output of
load_information_from_description_file to disable the
auto-install of modules during local testing. It was naively adapted for
v16.0 by replacing the corresponding methods. Since a lru cache was added
(nice optimization in most cases) this is an issue because running lint
test afterward will get the cached value with an incorrect autoinstall
value. It makes sens to avoid reading the file on the filesystem each
time, but making a deepcopy looks like an acceptable safeguard to avoid
hard to debug behaviors.
closesodoo/odoo#143628
X-original-commit: ad10ff4410ccf7c38f6154480484495bb57c53ff
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
This will help the upgrade process. Currently, there is an harcoded[^1]
inherit tree stored in the upgrade source. By storing this information
in the databases, we:
- avoid this hardcoded list.
- support more than the standard modules.
task-3504720
[^1]: hardcoded, but autogenerated.
closesodoo/odoo#140261
Signed-off-by: Raphael Collet <rco@odoo.com>
If upgrading a database across an addition of a new field to
ir.module.module (which is uncommon but does happen), the field
prefetching would try to load the field before the database schema had
been upgraded, leading to a loading error.
Since we *only* want / need the module's name, we can `search_fetch`
to preload just the field we need, and avoid ancillary
prefetching. It's a bit of an unnecessary optimisation compared to
just turning prefetching off, but it's also simpler (shorter) here
so...
closesodoo/odoo#140010
X-original-commit: c0102ca5dc3507c39f5ae6406fd962419fb09c6e
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is a preparation for the new page from template feature.
In order to make it possible for new page templates to be customizable
at several levels from themes, it was decided to create several layers
of primary templates.
Those templates are build from the descriptions found in manifest files
under the new `new_page_templates` key.
The same principle is also applied for configurator pages (described in
manifest files under the `snippet_lists` key) because we noticed that
some of the changes that were made in themes for some blocks were not
supposed to impact the "drag'n'drop" version of the block, but only
the version used inside the pages generated by the configurator. (E.g.
connecting shapes between blocks)
The manifest entries now have the following structure:
```py
'snippet_lists': {
'somepagename': ['s_block_name', ...],
},
'new_template_pages': {
'somecategoryname': {
'sometemplatename': ['s_block_name', ...],
},
},
```
This commit finds those entries in the manifests and creates the
following primary templates:
- `s_block_name`: already exists, this is the block that is drag and
dropped using the website builder
- `configurator_s_block_name`: specialization of `s_block_name` used in
all pages generated by the configurator
- `configurator_somepagename_s_block_name`: specialization of
`configurator_s_block_name` for that specific page
- `new_page_template_s_block_name`: specialization of `s_block_name`
used in all new page templates
- `new_page_template_somecategoryname_s_block_name`: specialization of
`new_page_template_s_block_name` used in new page templates of that
specific category
- `new_page_template_somecategoryname_sometemplatename_s_block_name`:
specialization of `new_page_template_somecategoryname_s_block_name` for
that specific template
For the template pages defined in `website` it also creates primary
templates that assemble `t-snippet-call`s of the most specific block
templates. Those templates are named
`new_page_template_sections_somecategoryname_sometemplatename`.
task-3381714
Part-of: odoo/odoo#126719
The issue with the t-cache (discribeds with a test in previous commit)
is that the key/value can be anything. It can be based on other t-cache
(assets in the example) but could be anything else.
The proposed solution will clear the t-cache when ANY other cache is
cleared. This is similar to the behaviour when the t-cache was
introduced (single ormcache)
Also sligly improve logging to precise what was cleared
closesodoo/odoo#138647
X-original-commit: aa69fa9f8efed0da45c601e5d57ce252446e376f
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Replace all the calls to get_resource_path to the better file_path or
directly use file_open when not needed
Doing both a get_resource_path and file_open means checking twice that
the file exists.
Doing a simple path concatenation before a file_open is safe.
If given to another method (e.g. etree.parse), calling file_path is
the prefered method.
Note that get_resource_path used to return False when the file does
not exists while file_path/file_open raises a FileNotFoundException
closesodoo/odoo#135607
Related: odoo/upgrade#5187
Related: odoo/enterprise#47475
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Since odoo/odoo#122569, we now try to import the `migrations`
sub-package of each module to find upgrade tests.
However, this badly written regex match the OCA module `base_maintenance`,
which generate a RecursionError.
closesodoo/odoo#136549
X-original-commit: abd9e6686bdb1f84d67bd536d9cecda627cd001a
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
The method get_resource_path is redundant with file_path but without
all the checks.
The method will be deprecated in master but make it use file_path in
stable.
closesodoo/odoo#136272
X-original-commit: 64ab4a6914dadd741cfe61d9bd1959ae4509a1ca
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
We explicitly discourage a compute method used for both stored and
non-stored fields, because it may be unexpectedly update the database.
Indeed, we don't expect the computation of a non-stored field to update
the database. Allowing this kind of compute method makes reasoning
about readonly code much more difficult, and would prevent readonly
transactions with such fields.
For instance, consider a compute method for both fields F (non-stored)
and G (stored), and assume that none of those fields are in cache.
Whenever F is accessed, the compute method is invoked, and both fields
are assigned, which potentially generates an SQL update for field G.
This is problematic if we require the current transaction to be
readonly.
Part-of: odoo/odoo#98565
a translation issue that only appears on Odoo.sh. On the
other systems and locally, everything works fine.
The problem seems to have its source in odoo.tools.translate
Here is the problem:
On the basis of staging (brutus), in the LIMS application, menu Report / Test reports:
* take report 000022. The client is in French.
* click on the button "preview PDF"
-> the values of the "state" column are not translated.
Locally (same sources, same database), these values are well translated.
This field is defined as follows:
```py
state = fields.Selection('get_state_value', string='State', copy=True, required=True)
def get_state_value(self):
return [
('init', _('Init')), ('conform', _('Conform')), ('not_conform', _('Not Conform')),
('unconclusive', _('Inconclusive'))
]
```
Here's what happens:
When the '_' method is called, another method ("_get_translation") is called.
It tries to determine which module is used. To do so, it is based
on the path (path) and use the "get_resource_from_path" method:
https://github.com/odoo/odoo/blob/16.0/odoo/tools/translate.py#L474
This method iterates over all defined addon paths. On Odoo.sh, these are:
```
'/home/odoo/src/odoo/odoo/addons',
'/home/odoo/.local/share/Odoo/addons/16.0',
'/home/odoo/src/odoo/addons',
'/home/odoo/data/addons/16.0',
'/home/odoo/src/user',
'/home/odoo/src/user/Logicasoft/base',
'/home/odoo/src/user/Logicasoft/lims',
'/home/odoo/src/user/Logicasoft/mail',
'/home/odoo/src/user/Logicasoft/web',
'/home/odoo/src/enterprise',
'/home/odoo/src/themes',
```
The path variable is equivalent to "/home/odoo/src/user/Logicasoft/lims/lims_base/models/lims_analysis_result.py"
As soon as the 'path' variable has a common prefix with one of the paths in the
mentioned list, Odoo considers that it has succeeded in finding the path that contains the module in question.
Locally, the path is: "/home/oli/work/bwt/sh/modules/user/Logicasoft/lims/lims_base/models/lims_analysis_result.py"
And the found path is: "/home/oli/work/bwt/sh/modules/user/Logicasoft/lims/"
But on Odoo.sh, the path found is: "/home/odoo/src/user/"
because Odoo finds that there is a common prefix. This is the case, but another path also has a common prefix: "/home/odoo/src/user/Logicasoft/lims" and this one is the correct one.
The result is that the module found is not the correct one:
- module='Logicasoft' on Odoo.sh
- module = 'lims_base' on other systems
Since the module is not the correct one on odoo.sh, the translation is not found.
Solution
========
when we have a module present in parent and child path we want to take the child path,
which is the long one, so we sort the list of paths by length which ensures that children
have priority on parents.
opw-3374757
closesodoo/odoo#133862
X-original-commit: 6ef7e188963b65a31589f8f15107ce698cd3dc74
Signed-off-by: Abdelouahab Laaroussi (abla) <abla@odoo.com>
This commit fixes a traceback when trying to install demo data from the UI.
Steps to reproduce:
- create a database with website_event_track_live installed and without demo data
- load demo data from the UI (settings)
- odoo.exceptions.AccessError: You are not allowed to create 'Website Visitor'
(website.visitor) records.
There is a traceback because the installer can't create `website_visitor`
records because there are no groups that have create access rights for that
model.
This is because xml_import used to get an environment with root privileges, that
can bypass access rights, but now the environment is a parameter passed to the
function and doesn't necessarily have sudo
This change was introduced in
5bf1207#diff-8e4705d5ab335a8dfc2c70eeedc502a92695989f97c4f19184b49634c2c4ad55L583-R583
; with this commit, the environment used by xml_import doesn't necessarily have
sudo, so we simply make sure `load_demo` loads data with sudo.
Task-3202914
closesodoo/odoo#129946
X-original-commit: 85834371e0eede05858cb2dc33412396c6e5c5bf
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Signed-off-by: Adrien Milis (miad) <miad@odoo.com>
The number of invalidation during the test is quite large and
the crons cal also spam this log sometimes.
Waiting for further cleanup, removing this log to avoid spaming runbot
logs and making them harder to read.
closesodoo/odoo#128921
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Considering the valid odoo version in the manifest version
The message before of this commit was:
Modules should have a version in format ``x.y`` or ``x.y.z``
It looks like it enforces to removing the odoo version part as invalid
But it is not, in fact, it is already supported
It is important since OCA enforces ``{odoo.version}.x.y.z`` format
It was already discussed here:
- https://github.com/odoo/odoo/pull/118420#issuecomment-1635047100
The message after this commit is:
Modules should have a version in format `x.y`, `x.y.z`, `16.4.x.y` or `16.4.x.y.z`.
Notice the Odoo version "16.4" is the current {odoo.version} for the moment this commit was done
It avoid confusing about the valid formats to use
closesodoo/odoo#128810
Signed-off-by: Christophe Simonis (chs) <chs@odoo.com>
Splitting the cached revealed a missing cache invaldation.
The cache invalidation added a a query in test_related_fields
The query can be avoid by not updating the xmlid if it is not useful.
closesodoo/odoo#119813
Related: odoo/enterprise#42527
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
One of the main issue with ormcache is that the invalidation clears
everything, meaning that some value, slow to compute but with a long
lifetime, can be removed from the cache because an easy to invalidate
value is cleared, like after writting or creating a product has an
example.
Most example in the code will try to invalidate the cache of the models
doing something like `env['ir.qweb'].clear_caches()` but it is
finally equivalent to `env.registry.clear_cache()`, and cross worker.
The idea is to have multiple cache, maybe with specific sizes for a
specific purpose.
Having one per model is maybe a bad idea because it will be difficult
to size the LRU correcly, and it is too dynamic. Checking invalidation
may be expensive.
The proposed solution is closed allow a limited number of named caches,
using onse sequence per cache. This is actually close to the
cache_longterm.
We want to discourage using a specific cache for one use case in
the buisness code. Adding a cache shouldn't be something easy, doable
in stable.
Note that we could also change the invalisation mecanism using an
insert only table. We an check the sequence of this table, but also
fetch all invalidation messages.
Another possible improvement, especially if we have more than x cache is
to have a global sequence, checking signaling would mean to check the
main sequence, and only the other ones if the main one changed.
Note that this poc is inspired from the long term cache but not all
use case where applie yet.
Part-of: odoo/odoo#119813
When user tries to import a module which does not consist of an icon and then
when user tries to access that module the error occurs.
Steps to reproduce:
1. Install web_studio.
2. Import a module(without icon) from apps > import module menu.
3. Now search that module in apps and click on module info.
4. The error will occur.
Applying this commit will fix this issue.
sentry-4206999375
closesodoo/odoo#124540
X-original-commit: 4b0221800ab75d5573e7066bf8beee14488062dd
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit includes the exception
details when logging an error in the registry module.
By importing the sys module and using the exc_info() method,
the commit ensures that the complete exception information is captured
by Sentry.
This modification improves the error reporting functionality
by providing more comprehensive information about the encountered
exceptions. This will aid in debugging and diagnosing issues,
enabling faster resolution of potential problems.
closesodoo/odoo#124318
X-original-commit: 55118b726bcd2532d2a7e67322eccb1ea6b75b7f
Signed-off-by: Achraf Ben Azzouz (abz) <abz@odoo.com>
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
pre_init_hook
When reinstalling a module, an error occurred if using env from
api.Environment in pre_init_hook.
Example:
- Module A depends on module B, and model M that created from module A
- When reinstalling module B, an error occurred if using env['M'] in
pre_init_hook
closesodoo/odoo#124086
X-original-commit: 70fcfa0d9cdf51964fce1a3be31bbd26258e2275
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Before this PR:
The only way to neutralize the database is running cli command neutralize
After this PR:
There is a new checkbox "neutralize database" in Duplicate database and Restore database dialog that neutralize the database after duplication/restore.
I also moved the neutralization code to the external module so it can be called also outside the cli .
closesodoo/odoo#122185
X-original-commit: 616740e9d09b3d0376be43ed1489e390f6f5823e
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
The introduction of Milk has brought new app icons.
Using the svg format creates a lack of anti-aliasing on the edges of the
shapes, which makes the icons look bad.
Since the png size has been reduced, we can afford to use the png format
to have the best possible quality without having a lack of performance.
task-3326633
Part of task-3326263
X-original-commit: e07cb722f2b11407a3ad093bd688b7d37afd5a88
Part-of: odoo/odoo#121886
Confusion between uninstall hooks can apparently trigger errors during
uninstallation as two hooks can confuse one another?
In this here case, the issue triggered during the uninstall hook of
`account_accountant`, which apparently combines with the uninstall
hook of `industry_fsm_sale` to trigger an invalid in-memory state for
`project_project`. An implicit flush during the hook then blows up
with a check constraint error.
Flushing at the end of the `industry_fsm_sale` hook or at the start of
the `account_accountant` hook fixes the issue, so might as well flush
after each hook to ensure whatever they did using models is pushed to
the database and in good shape (hopefully).
X-original-commit: b28e9a7066d29d395421a11df2b9e170fb20d35a
Part-of: odoo/odoo#121522
When inside an HttpCase, the end of a successful request will
`signal_changes` meaning that the registry_invalidated flag is removed.
A second issue is that this flag is thread local meaning that if a
request set the flag, it won't be visible from the test thread.
For those reasons, this commit ensures the registry sequences are
incremented as in production mode, and adds a check that the sequence
didn't change during the tests, calling `setup_models` the registry
manually if needed.
closesodoo/odoo#121268
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
mimic what is done for `odoo.addons` __path__.
closesodoo/odoo#121211
X-original-commit: 2a981e6a561f572742202d9c964d3b1f3aecacf9
Signed-off-by: Christophe Simonis <chs@odoo.com>
As module versions can be single digit, an upgrade script for version
`x.y.z`, is currently parsed as an upgrade script for module
version `z` in Odoo `x.y`.
However 3-digits module versions are more common than single-digit ones
and developers may expect the `x.y.x` upgrade scripts to be major-less
scripts.
This ambiguity can lift off if we accept module versions to be **only**
2-digits or 3-digits. This however make the `x.y.z` upgrade script
major-less. This can be fixed by renaming the script to `x.y.z.0`.
Part-of: odoo/odoo#118420
When instantiating a new registry, this piece of code is called
try:
odoo.modules.load_modules(registry, force_demo, status, update_module)
except Exception:
odoo.modules.reset_modules_state(db_name)
raise
For a new database, load_modules will create the table ir_module_module
in the same transaction as everything else. This means that if any error
occurs, the transaction is rollbacked and the table ir_module may not
exist.
`reset_modules_state` will try to access ir_module_module table leading
to another error and an unecessary and confusing error log.
2023-04-26 12:05:34,823 616958 ERROR ? odoo.sql_db: bad query: UPDATE ir_module_module SET state='installed' WHERE state IN ('to remove', 'to upgrade')
ERROR: relation "ir_module_module" does not exist
LINE 1: UPDATE ir_module_module SET state='installed' WHERE state IN...
^
2023-04-26 12:05:34,823 616958 ERROR ? odoo.modules.registry: Failed to load registry
2023-04-26 12:05:34,824 616958 CRITICAL ? odoo.service.server: Failed to initialize database `test-base`.
Traceback (most recent call last):
File "/home/xdo/osrc/master/odoo/odoo/modules/registry.py", line 90, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/xdo/osrc/master/odoo/odoo/modules/loading.py", line 386, in load_modules
raise Exception('An error')
Exception: An error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/xdo/osrc/master/odoo/odoo/service/server.py", line 1302, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-14>", line 2, in new
File "/home/xdo/osrc/master/odoo/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/xdo/osrc/master/odoo/odoo/modules/registry.py", line 92, in new
odoo.modules.reset_modules_state(db_name)
File "/home/xdo/osrc/master/odoo/odoo/modules/loading.py", line 622, in reset_modules_state
cr.execute(
File "/home/xdo/osrc/master/odoo/odoo/sql_db.py", line 311, in execute
res = self._obj.execute(query, params)
psycopg2.errors.UndefinedTable: relation "ir_module_module" does not exist
LINE 1: UPDATE ir_module_module SET state='installed' WHERE state IN...
With this commit, we check the ir_module_module table existance avoiding
an exception and revealing the minimal traceback.
2023-04-26 12:11:21,218 617810 INFO ? odoo.modules.loading: skipping reset_modules_state, ir_module_module table does not exists
2023-04-26 12:11:21,218 617810 ERROR ? odoo.modules.registry: Failed to load registry
2023-04-26 12:11:21,218 617810 CRITICAL ? odoo.service.server: Failed to initialize database `test-base`.
Traceback (most recent call last):
File "/home/xdo/osrc/master/odoo/odoo/service/server.py", line 1302, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-14>", line 2, in new
File "/home/xdo/osrc/master/odoo/odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "/home/xdo/osrc/master/odoo/odoo/modules/registry.py", line 90, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/xdo/osrc/master/odoo/odoo/modules/loading.py", line 386, in load_modules
raise Exception('An error')
closesodoo/odoo#119820
Exception: An error
Signed-off-by: Raphael Collet <rco@odoo.com>
When we compare majorless scripts we must ignore the Odoo version.
Otherwise a module upgrade without major Odoo upgrade would fail to run
local scripts majorless scripts. That's what happens for example when
users click the upgrade button of a module.
Example: upgrade from `11.0.1.0` to `11.0.2.0`, with a local `2.0` folder
for upgrades.
```
11.0.1.0 < 11.0.2.0 < 11.0.2.0 -> False (check before this patch)
1.0 < 2.0 <= 2.0 -> True (check with this patch)
```
While still: upgrade from `11.0.2.0` to `12.0.2.0`
```
11.0.2.0 < 12.0.2.0 < 12.0.2.0 -> False (before this patch)
2.0 < 2.0 <= 2.0 -> False (with this patch)
```
closesodoo/odoo#119203
X-original-commit: 84ab74c62a19d08de8b6c7c4e3f3300d7e79bcf9
Signed-off-by: Christophe Simonis <chs@odoo.com>
odoo/odoo#111651 improved and optimised triggers but dropped the
in-place cleanup of field dependencies. As a consequence, during
module uninstallation if a stored computed field is removed (because
it's part of a module being uninstalled), and one of its dependencies
is subsequently altered (e.g. it's itself removed, or written to) the
second update will break as the query trying to find out which
dependent records to update will error, either because of trying to
select / filter on a missing column, or because of trying to fetch
in a missing table.
The simplest examples of this issue are computed fields with a
dependency on `ir.model`:
- In `calendar`, `calendar.event.res_model` is a related on
`res_model_id.model`, this prevents the removal of *any* `ir.model`
record if it gets uninstalled.
As a result the `calendar.attendee` and `calendar.event` tables
don't get removed (just emptied of all their non-automatic fields),
their records remain as well, and when the non-automatic fields get
re-added during installation re-instating the NOT NULL constraints
fails, breaking the uninstall/reinstall test.
- In `payment`, `payment.provider.module_state` is a related on
`module_id.state`, this breaks *during* uninstallation, as after
`module_uninstall` first calls `_module_data_uninstall` which
removes the field, then it *updates the modules being uninstalled*
(sets their state), which tries to find out which
`payment.provider`'s `module_state` is should update, which breaks
because the `module_id` column has been removed.
This second one was worked around in odoo/odoo#118900, by marking
modules as uninstalled before actually gutting them, but as it turns
out the "actual" fix is needed anyway. So revert the workaround, and
actually fix the issue.
closesodoo/odoo#119130
X-original-commit: 48a420efcf7c7b46416bab006003553cc9d23846
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
The TriggerTree class does not have a specific __repr__(). It thus
falls back on dict's __repr__(), which does not show the root of the
tree. This makes debugging hard and confusing.
closesodoo/odoo#113521
Signed-off-by: Raphael Collet <rco@odoo.com>
Odoo Test environments requires to modify many parts of the unittest
TestCase, Suite and Result.
The main initial reason is to **avoid to postpone result at the end of
the test suite**, because even if it is convenient to have all errors
visible after the tests in some case, odoo logs adds information during
the execution that can be useful to debug when a test fail, to have
context for an error. (see **OdooTestResult**)
We are also fixing the stack trace comming from a unittest and since
there is no proper way to hook inside the TestPartExecutor, a dirty hack
injects anoter result on the outcome to manage the error and complete
the stack trace. This was also a way to avoid to postpone subtest logs
at the end of the test case (see _ErrorCatcher)
`_feedErrorsToResult` was used to test the test suite behavior since
there are many customization and this is quite fragile, especially if
unittest changes behavior in other python version.
**Python 3.11** introduced python/cpython#664448d8 That, in a way, goes
in the same direction of the changed introduced with _ErrorCatcher:
immediately feed errors to resut instead of postponing it. But this also
removes `_feedErrorsToResult` that was used to test this behaviors, as
well as other ones.
Since odoo should remain multi-version, this amount of changes on the
initial behavior become to complicate to keep cross-version and the
(already in our mind for a while) solution to **vendor unittest** will
help to simplify most of our test code base.
This commit modified the vendored unittest files to simplify them as
much as possible to suite our needs.
Since the runner is still the unittest one, we need to inherit from
unittest.Testcase in order to have the right type.
This also means that we still have access to all TestCase methods
without overriding them all. This is convenient for assertion methods as
an example but the initial idea is to vendor our own version of TestCase
to avoid having trouble to adapte our miscommunications to future python
versions. A trade-off must be done to chose what should remain in our
code base. The idea is to keep logic closely linked to our changes in
our code base, mainly around the run method, but also addClassCleanup
wich need to be vendored for python 3.7, but assertions methods are
independent. Any logic can be moved fom unittest to our
vendored version in the future if needed.
X-original-commit: 9a5d1ea54be49e4cc8208c33e76a6bbd2414d5d0
Part-of: odoo/odoo#113850
Consider field F in module X with parameter translate=False, and F is
overridden in module Y with parameter translate=True. During the
upgrade of module X, module Y hasn't been loaded yet, and the ORM
considers the field to be `translate=False`. Therefore it converts its
database column from type jsonb to varchar, and accidentally drops
non-en_US values:
{"en_US": "English value", "fr_FR": "French value"} (jsonb)
-> 'English value' (varchar)
As a result, translations are lost after upgrade.
This commit fixes the bug by checking whether the field is translated in
database and patches the field accordingly when loading the registry.
This avoids the ORM considering the field as non-translated while
upgrading modules.
In order to "force" translated fields to become non-translated ones, at
the end of the loading process the patch above is discarded, and fields
are checked again. We then adapt the schema of models that have such
fields. This extra step handles the uninstallation of modules like
module Y in the example above.
The patching of the fields has one potential issue. While upgrading
module X, field F is patched with translate=True. If module Y actually
overrides F with translate=xml_translate or so, this may cause the
behavior of the upgrade to be slightly incorrect. Because of the
complexity, we have chosen to not support this case.
closesodoo/odoo#112223
X-original-commit: 1e6e482a9763baa5fae70d9b6676d16a46458f4a
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Wang Chong (cwg) <cwg@odoo.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
The class is a simple extension of dict, and adds an explicit attribute
for the content of the root node of a tree. It makes the code much more
readable with very small performance overhead.
closesodoo/odoo#111946
X-original-commit: 8a01d74e5f7d035cfd05bc02596f075270e0fcf8
Signed-off-by: Raphael Collet <rco@odoo.com>
This patch optimizes the way field trigger trees are computed. Overall,
the resulting trigger trees are mostly identical, but they can now be
determined one by one, which enables an on-demand approach and partial
cache.
Before this patch, getting the first trigger tree proceeded as follows:
- resolve the dependencies of all fields;
- compute the transitive closure of the dependencies of all fields;
- store the transitive closure above as field triggers for all fields
in a cache.
After this patch, getting the first trigger tree proceeded as follows:
- resolve the dependencies of all fields;
- cache them as direct triggers for all fields;
- compute one trigger tree as the transitive closure of the field's
triggers, and cache it.
This optimization is quite effective during the installation of modules,
and is even more effective when the number of fields is large. For
instance, a complete installation with all community modules is now 25%
faster. For a complete installation with all enterprise modules, the
installation time is even 30% less! A medium installation is about 16%
less time.
The optimization also speeds up the first request on a new Odoo worker,
since the minimum time for computing a handful of trigger trees is much
smaller than before. We have measured times for a first request going
from 1.6 seconds to 1 second for posting a message.
We have observed slight differences in trigger trees, but they occur in
places where the tree has redundant branches, in particular with fields
having recursive dependencies. It therefore makes no difference in what
is being triggered or invalidated.
X-original-commit: 68f786d494c3c73a085cd919b348c019f77794e7
Part-of: odoo/odoo#111946
Those APIs are aimed at hiding the implementation of trigger trees,
dependent fields and fields modifying relations. Explicit APIs simplify
the profiling of executions and comparison of implementations for
building trigger trees.
X-original-commit: d12b9270375634e738f5288d0c523ac0eec2fa18
Part-of: odoo/odoo#111946
Seems unnecessary, most of the information already lives in
`sys.modules`. We can just check that.
There are a few changes in behaviour, but they seem minor:
- if post_load fails, subsequent attempts to load the module will
"succeed"
- since we didn't remove/reload the module, a failure because of an
incorrect post_load wasn't fixable, however it was possible to
update the manifest
Still seems like a wonky state to be in, and one we should ignore.
Also remove the logging of the error: since we're re-raising as-is,
the parent logs it with a traceback, so this is unnecessary and
redundant.
closesodoo/odoo#103933
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>