Commit Graph
265 Commits
Author SHA1 Message Date
Xavier ALT af2eaae941 [FIX] core: add UPDATE as valid many2many command in SSF
This commit fix the "Unsupported M2M command 1" raised `Form` helper.

The `onchange()` method will in fact emit UPDATE command for many2many
fields when the value submitted an the one in database has changed
(this is the case for example for nested m2m in form views)

OPW-2044631

closes odoo/odoo#59943

X-original-commit: 76bd8208a416cefab6becff9f2d7204c7d196201
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Xavier ALT <xavieralt@users.noreply.github.com>
2020-10-14 08:23:22 +00:00
Nicolas Martinelli 481d1393e7 [FIX] base_setup, website, tests: remove Gengo references
The Gengo modules were removed with:
https://github.com/odoo/odoo/commit/b38b72e456a
https://github.com/odoo/odoo/commit/9b1f0962baa

But there are still references to it.

opw-2349904

closes odoo/odoo#58938

X-original-commit: a30edba504aa1b62aa02092112a55bca65cf9a0c
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
2020-10-01 17:34:27 +00:00
Christophe Monniez 103d8f012e [IMP] tests: use concat demuxer to encode frames
When the sceencast argument is used to produce a video file of failing
tests, the framerate is computed with a KISS average.
This results in a misleading video flow. For example, if a tour step is
stuck, the average could show a smooth transition instead of the reality.

With this commit, the real duration of frames are used to produce the
video. The result is a more realistic video flow.

The configuration text file used by the ffmpeg concat demuxer is kept
alongside with the video file so that it can be used for other purposes
(e.g.: parse the durations to be used by a video player on runbot).

closes odoo/odoo#58280

X-original-commit: 58eb6a4565c024077557fa2de83fdf831e5ef026
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2020-09-22 19:41:09 +00:00
Xavier Morel 2da6bc2730 [FIX] base: virtual group fields on users with new default/onchange
* override `onchange` in res.users in order to properly generate and
  send the reified group fields alongside the rest: while default_get
  sets them up, those fields then get stripped by the onchange
  machinery as they don't actually exist on the model
* add a test to check for it
* fix SSF in relation with the new default/onchange system
  - because fields may not actually exist on the record,
    `record_to_values` needs to `read` the record data rather than
    directly access the recordset: the recordset likely will not
    know about fake fields
  - after the initial onchange has run the form must be filled with
    falsy values in case the onchange has not sent defaults for
    everything
  - on creation, all fields in the form should be considered modified

Task 2341153

closes odoo/odoo#58152

X-original-commit: f8658f229180a595d69cd6daefeded082c7f64ea
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-09-21 14:53:29 +00:00
Raphael Collet e8f7cfd00a [FIX] core: cursor hooks API and implementation
Python 3.8 changed the equality rules for bound methods to be based on
the *identity* of the receiver (`__self__`) rather than its *equality*.
This means that in 3.7, methods from different instances will compare
(and hash) equal, thereby landing in the same map "slot", but that isn't
the case in 3.8.

While it's usually not relevant, it's an issue for `GroupCalls` which is
indexed by a function: in 3.7, that being a method from recordsets
comparing equal will deduplicate them, but not anymore in 3.8, leading
to duplicated callbacks (exactly the thing GroupCalls aims to avoid).

Also, the API of `GroupCalls` turned out to be unusual and weird.  The
bug above is fixed by using a plain list for callbacks, thereby avoiding
comparisons between registered functions.  The API is now:

    callbacks.add(func)     # add func to callbacks
    callbacks.run()         # run all callbacks in addition order
    callbacks.clear()       # remove all callbacks

In order to handle aggregated data, the `callbacks` object provides a
dictionary `callbacks.data` that any callback function can freely use.
For the sake of consistency, the `callbacks.data` dict is automatically
cleared upon execution of callbacks.

Discovered by @william-andre

Related to odoo#56583

References:

* https://bugs.python.org/issue1617161
* python/cpython#7848
* https://docs.python.org/3/whatsnew/changelog.html#python-3-8-0-alpha-1
  (no direct link because individual entries are not linkable, look for
  bpo-1617161)

X-original-commit: d4b2e9224839aed8fc160ebe5a89e0f7d4c6a5bb
2020-09-03 14:29:39 +00:00
Thibault Delavallée 1404af789c [REF] various: use helper to create tests users
PURPOSE

Lessen use of mail-specific calls and variables

SPECIFICATIONS

Use mail_new_test_user tool in tests, lessening use of mail-specific context
keys in tests.

LINKS

Task ID-2326281 (context keys use cleaning)
PR odoo/odoo#56631
PR odoo/enterprise#12707

X-original-commit: 910559c092dc7dfa00b91339a5423e16cd4668e1
2020-08-28 07:59:23 +00:00
Luis González 4debe9f1fa [FIX] tests: Handle attrs containing numbers instead of bool
The Form class already handles cases for attrs that contain boolean
values, e.g.:
`attrs="{'readonly': True}"`

But it doesnt for integers, e.g.:
`attrs="{'readonly': 1}"`

This commit changes the expected non-domain value from boolean to
integer, because both are valid cases and the former is a subset of the
latter.

[1] https://github.com/odoo/odoo/blob/b3d4938ba6b1/addons/repair/views/repair_views.xml#L54

closes odoo/odoo#56612

X-original-commit: 782534a429f10e7b114c838687d38aa4080a920c
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Luis González [Vauxoo] <luisg123v@users.noreply.github.com>
2020-08-26 15:36:43 +00:00
Raphael Collet 488e334fc8 [REF] core: combine default_get() with first onchange()
When creating a new record, the client calls `default_get()`, completes
the returned values with `False`, and calls `onchange()` to apply the
onchange to the defaults.

Optimize the double round-trip by integrating `default_get()` inside
`onchange()` for the first call.  The method is called with an empty
list of fields, and usually no field values, except for records in a
one2many field.  In this case, `onchange()` does both steps above.

Task 2261084
2020-08-20 13:39:04 +00:00
Xavier Morel a3ec322993 [IMP] core: tests reporting
* remove useless OdooTestRunner
* don't log results & time per-file, log a module-level tally instead
* add number of tests to post-test results
* generate a single test suite per module (see note)
* use the previous item to split out the at_install test-running in
  two steps: generating the suite for the module then running that
  suite, this way for modules which have no test, or for
  which all tests have been deselected by test tags, we can avoid some
  of the setup necessary to prepare for running tests but possibly
  quite expensive (e.g. `setup_models`)

Note: single test suite per module

I wanted to stop creating a test result for (essentially) every file
in the module, however because of the class-level ``addCleanup``, a
TestResult can't be reused by independent suites:

In order to run class-level cleanup, the test suite checks between
tests if the test it's *preparing* to run is in the same class as the
last test it ran, and if not applies the class-level cleanup.

The problem is that the "previous test class" is stored on the result
object, which is never cleaned up, and the "between tests" check is
really performed *before each test*.

This means when reusing results across suites it will run the
class-level cleanup at the end of one suite and immediately at the
start of the next, which will cause issues if class-level cleanups are
not idempotent (thankfully ``TestTestCursor`` has a non-idempotent
``tearDownClass` which let me discover the error).

Possible fixes are:

* don't reuse results
* clear the relevant states / attributes between suites
* put individual suites in a Big Suite for running

The latter seems simpler: just create a single suite for the entire
odoo-level module instead of creating one suite per test module.

Note to the note: the case of nested suite is taken in account, the
"end of suite" cleanup only runs at the end of the top-level suite, so
technically we don't have to unwrap suites for *that* purpose, we're
doing so in order to filter the test cases inside the suites. But
maybe we could integrate this feature to the suites themselves...

closes odoo/odoo#55185

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-08-19 14:08:21 +00:00
Xavier Morel c1c43bbe38 [REM] core: assertion reports
That's a not-very-useful subset of OdooTestResult, so:

* make results merge-able (aka add ability to update a result with the
  contents of another)
* remove support for test data files, and transmission of the
  assertion report thing through the data-files loading
* replace "legitimate" uses of assertion report by test result
* have run_unit_tests manipulate and return a result instead of weird
  flags & ternaries
2020-08-19 14:08:12 +00:00
Xavier Morel ec8a64a85c [REF] core: move testing-related functions to odoo/tests submodules
Attempts to clean up odoo/module and odoo/service a tad, they still
invoke testing-related utilities but are more logical in what
they *contain*.
2020-08-19 07:28:44 +00:00
Xavier Morel dccbf425a1 [FIX] core: ensure we create a new session for each tour
The browser itself would get mostly cleaned up between tours, but the
session object would not get cleaned, and apparently in some cases
that could lead to an incoherent session: a tour would add data to the
session which the next tour (logging in as a different user) would
not (fully) override, leading to a session inconsistency and a Session
Expired exception during the tour.

Fix by not storing the session on the test object, the session is
created during authentication then set on the opener & browser.
2020-08-14 21:20:47 +00:00
Xavier Morel 950d962d95 [IMP] core: add env to various auth methods
Allows accessing various keys, especially whether this is an
interactive login or not.

Also have the xml-rpc `login` delegate to `authenticate` instead of
having its own half-assed implementation.

And remove some dead code: as far as I can tell, Session.authenticate
is never called with a uid.
2020-08-14 21:20:47 +00:00
Laurent Smet 34d53ebc87 [REF] account: Add generic 'AccountTestInvoicingHttpCommon' class
Thanks to this setup, we will be able to run the tours independently to any demo data.
To do so, the HttpSavepointCase is born to do the same as HttpCase but with a setUpClass.

--task: 2290120
2020-08-06 11:20:27 +00:00
Xavier Morel b3761a8cba [FIX] core: fix handling of removals in sub-o2m
Issue is specifically in the case of an onchange removing a record in
an o2m in an o2m (so a sub-o2m) if loading an *existing* record in the
SSF: since the server pretty much only returns a REMOVE_ALL followed
by the records to keep or create, conserving the removal information
requires diffing the value currently stored in the form and the result
fo the onchange.

Diff which was properly done for top-level o2ms, but not for the ones
below that (apparently forgot this bit when improving support for
nested o2ms earlier this year).

X-original-commit: 177d009541cca589c6ebb85fc051b893ec001536
2020-07-20 11:42:58 +00:00
Raphael Collet dd8a6b8a82 [ADD] test_new_api: tests on queries made by create with computed fields
closes odoo/odoo#54209

Related: odoo/upgrade#1464
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-07-08 11:58:33 +00:00
Xavier Dubuc 5afc70faef [FIX] mail: fix open thread in discuss
See also odoo/enterprise#11684
task-2282273

closes odoo/odoo#54141

Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2020-07-06 14:23:17 +00:00
fja-odoo 7630ef3388 [IMP] website: add tests for website_visitor
website visitor testing had some flaws.

task-2079873

closes odoo/odoo#52281

X-original-commit: 4e5f049e48f06eb4be2a9972d06167e68bba1d61
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
2020-06-02 16:08:43 +00:00
Raphael Collet 020536142c [IMP] core: better tests on queries made by search 2020-05-20 07:56:14 +00:00
Xavier Morel fbfd36aabb [FIX] core: fix _cleanup_from_default
Technically removing the entire thing if it's not one of the special
cases is a form of cleanup I guess, but that seems a bit brutal and
counter-productive. So that function should *probably* return the
input value if it's not a type which requires special processing.

closes odoo/odoo#51531

X-original-commit: b42994c87dce12c5ba22943f6cbe00240fe43138
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-05-19 11:08:20 +00:00
Xavier Morel ac3cb21836 [FIX] SSF: handle o2m nesting
The SSF had pretty much punted on nested o2m as that's... not usually
a concern because few people are insane enough to put o2ms in their
o2ms in their views. And also because even if somebody did, sometimes
nothing would break because it turns out to be pretty difficult to
actually get into *using* those things.

MRP managed to do it though, and repro-ing required copying over parts
of mrp.production and then understanding why it didn't fail:

* obviously needs an o2m (f1) which contains an o2m (f2), in the
  view (an invisible tree inside a visible tree)
* needs an onchange which somehow updates the sub-o2m
* needs to actually trigger an onchange on the root form for f1,
  meaning f1 must be a dependency of a compute field or something (here
  I just marked every damn field as on_change as the optimisation of
  "don't call onchange when there's no need to" doesn't matter)

Also needs to be working on an existing record with existing
lines *and sublines* as the issue occurs with records to update.

The issue here is that `_onchange_values` would clean up f1 e.g. send
nothing for unmodified entries, and only send modified fields
otherwise, but it would only do so for the toplevel, meaning the
sub-level would not go through this step, and could send UPDATE
commands with an `id` field (set to the original value but
still). This would then proceed to blow up while loading the record,
as id fields are not writeable.

The fix is to perform `_onchange_values` recursively. Do that using a
separate helper in order to avoid blowing up on override and whatnot,
or faffling about with weird branching to get the "default" values in
case they're not provided, the root function can get all the relevant
bits and call the helper with them, then the helper does that setup
internally and calls itself directly.

An other issue I stumbled upon when investigating is a similar problem
on *save*, due to an implementation detail of the SSF: UPDATE commands
are fetched lazily.

`_values_to_save` took care of "hydrating" all update commands (and
validating and filtering them) of modified o2m fields, but as it would
not do so recursively a modified f2 would not get properly hydrated
and filtered, and could try to write `None` onto existing records.

closes odoo/odoo#51350

X-original-commit: 3dfb4cfad849936748cc6a5b8f712e100461a86f
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-05-15 14:53:20 +00:00
Christophe Monniez 277aa01112 [FIX] tests: wait for Chrome tab to appear
From time to time (frequently on Mac OS), the Chrome tests are failing
because there is no tab found in the browser instance.

It seems that in some circumstances, the browser is started but the tab
takes some times to appear, for that reason, the tab information is not
available in the first json commands.

With this commit, the json command is issued multiple times with an
increasing delay until the desired key is found in the json answer, or
until the timeout is reached.

closes odoo/odoo#50784

X-original-commit: 4b12643abc6b8ba34f14e468e8d7760bc2db385b
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2020-05-06 17:18:07 +00:00
Ronald Portier eae51e5fa8 [FIX] core: SSF should re-read from the record after saving
Before this change, the SSF would read from the record after
creation but wouldn't do so after a write.

This doesn't conform to the behaviour of the web client (which does a
read() after saving a form), and means the effect of field
inverses (when the dependencies of a writable field are also in the
form) or overrides to write wouldn't be visible afterwards.

It's always possible to just re-create the form from scratch, but the
intention has always been that the form would work correctly after a
save.

closes odoo/odoo#50363

X-original-commit: 45398c09c0231e61b83d378d5939ec12d7465844
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-04-29 07:31:00 +00:00
Adrian Torres ca91e13dee [IMP] testing: forbid module operations during testing
With this commit, module operations such as install, upgrades and
uninstalls are henceforth forbidden inside unit tests and instead such
tests must be performed with standalone Odoo scripts.

This is done because module operations during tests are not
transactional, this can leave the registry in an unclean state and
further tests may be affected by this, it also creates a new registry
which complicates registry cleanup if anything crashes,
because the registry to be cleaned up is not the same one that crashed.

Instead, what should be done is a script that imports odoo as a library,
and loads the database necessary then performs whichever operations
necessary. This script should contain a single function with a single
parameter (env) and should be decorated with
@odoo.tests.common.standalone in order to be executed properly, this
decorator accepts any amount of positional parameters as tags that can
be specified when calling the script in order to execute only a select
subset of scripts.

Special tags are: 'all' and <module_name>, these are generated
automatically, the first will execute ALL scripts available whereas
<module_name> will execute all scripts introduced by said module.

When calling the test_module_operations script, only scripts found in
*installed* modules will be executed, script discovery is only possible
if the code is loaded therefore it is only possible if the module is
installed.

closes odoo/odoo#49669

Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
2020-04-22 07:45:53 +00:00
Romeo Fragomeli fbd1d7584a [FIX] tests,tools: remove unused code
Due to this commit: odoo/odoo@0ea67467b1 ( https://github.com/odoo/odoo/blob/0ea67467b1301b39a263a386a622e931784eb0de/odoo/tools/config.py#L521 )

the screencasts value is not a string anymore but a valid PATH.

So now you can't set '1', 'true' or 't' to force to have the
same directory as the screenshot dir.

Steps to reproduce:
odoo-bin ... --screencasts 1 (with a failed JS test to produce a screencast)

closes odoo/odoo#49665

X-original-commit: ab1bf59a3b78f3c0857755cb2439636b6df297c3
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Signed-off-by: rfr-odoo <rfr-odoo@users.noreply.github.com>
2020-04-16 13:28:07 +00:00
Romeo Fragomeli f91665ac66 [FIX] tests: ffmpeg don't use the right path for screencast
Screencasts were saved in the right directory (screencasts_frames_dir)
but the given path for ffmpeg was wrong (screencasts_dir) and it wasn't
possible to read theses files to make the video.
After this commit, we use the screencast_frames folder to read files.

Steps to reproduce:
Execute Odoo with these additional command:
--screencasts "folder_of_destination" --test-enable (with a failed JS test to produce a screencast)

X-original-commit: 0c0b7a656388d65de15796f07a3f4cc93028f1d7
2020-04-16 13:28:06 +00:00
Xavier Morel bfcda158fe [FIX] core: logging of arguments remoteobjects
odoo/odoo#46024 improved the serialisation of arrays being logged (in
order to get more relevant data than just `Array(5)`.

However, chrome apparently serialises *argument* objects as array-like
with a few nits, namely that arguments have non-numeric properties
which don't necessarily have a value associated with them.

The array formatter / converter assumed all properties had a value,
resulting in the process crashing rather dramatically.

Filter out non-numeric properties on arrays.

closes odoo/odoo#49418

X-original-commit: 5ff1e41c98f042fd13a1762977cc76604231dfd4
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-04-10 12:55:09 +00:00
Adrian Torres 5952928b42 [REM] *: remove various unused import shims
Before this commit, a lot of leftover import shims existed in the
codebase for py2-py3 compatibility, these are no longer needed since
Odoo 13.0+ doesn't support Python 2 anymore and is (finally) in EOL.

With this commit, these shims are dropped, making the code cleaner,
easier to read and with one less dependency.

Queue -> queue -> py2-py3 compatibility
xmlrpclib -> xmlrpc.client -> py2-py3 compatibility
ConfigParser -> configparser -> py2-py3 compatibility
itertools.izip_longest -> itertools.zip_longest -> py2-py3 compatibility
urllib -> urllib.request -> py2-py3 compatibility
__builtins__ -> builtins -> py2-py3 compatibility
_winreg -> winreg -> py2-py3 compatibility

mock -> unittest.mock -> merged into CPython

The debian/fedora packages and requirements.txt have been updated accordingly

closes odoo/odoo#44601

Related: odoo/enterprise#8141
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-04-01 12:45:40 +00:00
Jeremy Kersten 90c0f1e960 [IMP] website: test_crawl dont follow external link
In case a controller with a relative url return an absolute link
the current crawler follow the redirect and all external link of this
external url too.

Now we don't follow redirection if it is on an other netloc that the
current one.

Part of https://github.com/odoo/odoo/pull/38950
task-2087641
2020-03-31 18:16:07 +00:00
Christophe Monniez 7e1481355f [FIX] tests: move post_install only warning into browser_js
This warning should only appear when Chrome is used.

closes odoo/odoo#48009

X-original-commit: 013b32f000520217af17b6e1ffe1872ec97afdf0
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2020-03-19 11:47:41 +00:00
Adrian TorresandRaphael Collet 0453566a76 [ADD] tests: add a script to test module uninstallation
With this commit, a new script "tests-uninstalls.py" is added in order to
test module uninstallation.

This script is a kind of standalone tool. It uses odoo as a library but
the odoo server is not started at all.

In its standard invocation, it tries an install/uninstall/reinstall
cycle for each all module found in the specified database.

By specifying '-U', it only tries to uninstall the comma separated list
of modules following the argument.

Be aware that this tool, will alter the database against which it was
invoked.

Co-authored-by: Raphael Collet <rco@odoo.com>
2020-03-02 16:07:06 +00:00
Xavier-Do b2b36524c2 [IMP] core: improve module loading logs
Performances from a general point of view can be difficult to track.
This commit proposes to improve logs in two ways:

The current logs only use the sql_counter, wich will only be updated
when a cursor is closed. In a test-enable install, this counter
is actually the queries of the tests wince the install cursor is
open untill the end. The first fix is to use bot sql_counter and
sql_log_count to have total queries untill now on closed cursor,
but also the current number of queries of the current cursor.

This means that the new log format will be
{nb} modules loaded in {time}, {loading_querie} (+{test_cr_queries}) queries
instead of
{nb} modules loaded in {time}, {tests_cr__queries}queries

Nothe that in the current version, {nb} is actually the total number of
loaded modules until now.

This commit also add an equivalent end log by module and change the
loglevel of module start on install (mainly usefull if an error occurs
before anything else is logged hidding the module causing this error.)

A cleaner runbot logger is also added, in order to be abble to call
_logger.runbot( instead of _logger.log(25. This will clarify the purpose
of such a log level.

closes odoo/odoo#47283

Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2020-03-16 13:21:57 +00:00
Raphael Collet 5771772b61 [FIX] core: do not force recomputation of fields on new records
The method `recompute()` should not recompute fields on new records.
This is both a speedup (those recomputations are not necessary), and
fixes an error following an `onchange()` (a field recomputed in an
environment with the wrong context.)

OPW 2184998

closes odoo/odoo#47545

X-original-commit: fa852ba1c5707b71469c410063f338eef261ab2b
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-03-12 17:46:06 +00:00
Xavier Morel 9b00d352a9 [IMP] core: logging of array remoteobjects
The old path would just return e.g. `Array(2)` for an array of size 2,
which is not very useful when trying to see if an array's contents are
relevant to an issue.

Turns out arrays are serialized pretty much exactly like objects
without a subtype, just with property names being indices instead of
keys. So add a case which formats such remoteobjects as
array-literal-ish.

closes odoo/odoo#46056

X-original-commit: 6d5639024fa0f7501efe836e5571cd45bb46b123
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-02-24 10:22:38 +00:00
Christophe Monniez 253d5341a4 [FIX] tests: remove memory limit for chrome headless
Since Chrome version 80, the V8 javascript engine is using an new
pointer compression feature [1]. This features tries to reserve more the
4GiB of memory. As a consequence, during HttpCase tests, odoo tries to
launch chrome headless in a subprocess but fails because of the
memory-limit-soft.

With this commit, the Chrome browser is spawned in a forked process
that removes the memory limit.

Also a new Chrome CLI switch is used to prevent crash reports to be sent
to google.

[1] https://v8.dev/blog/v8-release-80

closes odoo/odoo#45859

X-original-commit: 726d9c50720c2d3c9e617e998ed0dcd12272a271
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2020-02-20 16:53:33 +00:00
Christophe Monniez 426fc163ba [FIX] tests: avoid confusing traceback at browser start
During an HttpCase, when the Chrome browser starts, it may happens that
the websocket is unreachable. In such a case, the stop method is called
and tries to stop the browser gracefully by sending a `Browser.close`
through the websocket ... which is not reachable.

The result is a confusing traceback. With this commit, nothing is sent
is the websocket is not available.

Moreover, the `sigxcpu_handler` attribute is used in the stop method but
not yet declared. Fixed by moving it before calling the _chrome_start
method.

X-original-commit: 0d156fd3bc114b40680ca5aa0456e0f21a5b8cff
2020-02-20 16:53:33 +00:00
Raphael Collet 058cf208a8 [ADD] sql_db: pre/post-commit/rollback hooks 2020-02-05 13:50:23 +00:00
Raphael Collet 73c2563b7e [FIX] tests: add flush during warmup to get correct query counts
In order to count queries exactly, the warmup phase of a test method
(decorator `@warmup`) must do the exact same operations as the normal
phase.
2020-02-05 13:50:23 +00:00
Damien BouvyandRaphaël Collet 8dab6caf46 [IMP] tests: add registry cleanups in Single and Savepoint tests
In some cases, the registry might be updated during a test step
(creating custom models/fields, for example).  In those cases, there
should be an explicit call to `reset_changes` on the registry to make
sure that the next test class starts with a registry that is consistent
with the database state.

Co-Authored-By: Raphaël Collet <rco@odoo.com>
2020-01-31 12:06:46 +00:00
Xavier Morel 5cfd32db9c [IMP] core: only show JS stacktrace for exceptions & console.trace
When revamping the message fetching from the headless browser, since
stacktraces are available (by default) on console.error and
console.warning events I assumed it could / would be useful to show
them in the Python-level log. And they *were* quite useful during the
original fixing stage.

However they turn out not to be very useful day-to-day:

* they add a lot of noise and lead to the error message itself being
  lost in a big block of red / logging.error
* when a tour fails (which is the vast majority of the failures) the
  JS stacktrace always points to the same location in the tour
  manager (the one which goes "this step never succeeded") which is
  completely useless
* aside from being bundled, normal JS code (where the stacktrace could
  be useful) doesn't generally use console.warn or console.error, it's
  going to straight blow up with an exception in which case we always
  get a stacktrace

Leave the stacktrace formatting for console.trace as that's pretty
much the only point of using this instead of console.log.

closes odoo/odoo#44343

X-original-commit: 34500853f39c9557852cb83cbc274f59d803922f
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-01-30 16:12:33 +00:00
Xavier Morel c4e075cf04 [IMP] core, web: test failure reporting
* remove misleading documentation about a "test failed" message, in
  13.0 any uncaught exception or console.error will cause the current
  test to be interpreted as failed
* fix tour manager to console.error its step and not add a second
  useless error message
* fix menu tester to try and display the failure cause on failure
* improve qunit's test reporter to print the number of tests failed in
  case of test suite failure

Should make test failures in tours a bit clearer.

closes odoo/odoo#44296

X-original-commit: 78121b68d099b16f2d775a7a8a963a2a0f474843
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-01-30 12:33:05 +00:00
Xavier Morel 0198c3e05d [IMP] core: reporting of browser logs / errors during setup
Sink handling of JS logging, exceptions and websocket timeouts so
calls other than _wait_code_ok handle them somewhat properly: the
issue fixed by odoo/odoo#41231 passed because it occurred during
module loading, which happens during initial page loading (browser_js
> navigate_to > _websocket_wait_event), which ignored logs (and
exceptions though here it's a console.error log), and as a result
reported no failure (and would simply miss that specific test as well
as every test following it).

Also since ChromeBrowser treats console.error as an exception,
important messages should be logged atomically. Merge two consecutive
console.error into a single one at the loading of modules so we don't
just get an exception "error while loading foo.bar" without any of the
useful details.

That ChromeBrowser treats console.error as exception is also why the
new method gets a flag (to suppress this behaviour): in the case of
two console.error, upon encountering the first it's treated as an
error so we try to take a screenshot, which goes through the messages
in order to get the screenshot response, which encounters the second
console.error, which gets treated as an exception, which hides the
first error.

Instead, screenshotting (and more generally _websocket_wait_id) should
treat console.error as a regular logging call, probably.

Also run JS tests in debug=assets for easier debugging (ha!) and
improve formatting of exception object when receiving an exception:
* if we can get a description on an `exception` remote object just
  print that, it's formatted to show the exception type, message &
  traceback
* otherwise format the garbage that is an "ExceptionDetails" object
2020-01-21 06:55:32 +00:00
Nicolas Lempereur b239201190 [FIX] *: avoid muting res.users().context_get return
Some code modify return of res.users().context_get, but this is a
cached method so this will unexpectedly affects totally unrelated code.

For example, changing the company with the company switcher could add
`allowed_company_ids` inside the cache, then it will be cached until the
server is restarted, even if we change company again inbetween.

Added test failed with:

"NotImplementedError: '__setitem__' not supported on frozendict"

on the line with `User = User.with_context(context)` where User already
contained `allowed_company_ids` in its context.

note:

in this forward-port, context_get is also changed to return frozendict
and prevent being able to have an unexpected issue by code that modify
context_get returns.

opw-2158340
closes #42465

closes odoo/odoo#42723

X-original-commit: 5d69885c1cd6921b3de00aae7e0ed6fff243ff95
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
2020-01-15 16:19:03 +00:00
Adrian Torres ee29cb9147 [FIX] tests: make --test-file great again
Sort of but not really, this commit fixes a special case in which
launching a --test-file of a file with at least two SavepointCases would
create a postgresql deadlock and it would be impossible to terminate the
Odoo process without sending a SIGKILL or waiting for the lock to
timeout.

This was introduced at #39368 and happens because of the way that
unittests unwraps suites, to keep it short, when it unwraps the custom
OdooSuite class internally, it ends up with a vanilla TestSuite with
which to run the different test cases, and since #39368 depends on the
overrides added to OdooSuite to function, the class cleanups are not
triggered at the end of a test class (rollback, cache cleanups, env
reset, registry reset, etc.).

The fix is to manually unwrap the suite of tests to keep OdooSuite as
the suite with which to call the tests, which was already done for
--test-enable (although for different reasons, --test-tags?) which is
why --test-enable didn't have any problems.

This commit also fixes a typo I found on the backport, which meant
classCleanups were not being executed if the setUpClass failed, but it
had no effect on classCleanups during tearDownClass.

Task-ID 2160398
Depends on #43135

closes odoo/odoo#43296

X-original-commit: 7a5ded7d40afc29043d356b5dece0dbe1fbd5ab3
Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
2020-01-14 16:26:50 +00:00
Xavier Morel 80896a0bf3 [FIX] core: chrome doesn't abide by --http-port anymore
An http-port provided on the command line (may also have been an issue
for config files, didn't check) would not be taken in account anymore,
because `odoo.tests.common` would be imported during the import of
`odoo` itself (when loading odoo.service.server), itself importing
`odoo.tools.config` leading to a default configuration being set up.

* remove `odoo.tests.common.PORT`, `config['http_port']` should be
  used always
* defer the import of odoo.tests.common by moving it inside
  load_test_file
* stop generating default configs

closes odoo/odoo#43283

X-original-commit: 45871f498ea4cf3ada719692e69cd413883ab442
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-01-14 13:15:04 +00:00
Xavier Morel 9d74b1f73a [FIX] core: saving of o2m value init'd via onchange
In the SSF, o2m updates get initialized with no values (1, id,
{}). The record data is only fetched when the "record" gets updated
explicitly from which updates will hopefully get properly tracked &
saved.

However if the "record" was first initialized through an onchange
values which are updated by the onchange (diverging from the db) those
would not get tracked and thus wouldn't get saved when the record is
saved.

* use more specific placeholder (None) for "o2m records to update but
  we don't have values yet"
* once we have values, always store them as an update-tracking dict
* if we don't have values yet for an o2m and an onchange is trying to
  write to it, initialize with values from database first (might
  eventually be a good idea to initialize upfront though there's the
  question of what happens for default values and recursive views)
* mark anything coming back from the onchange and differing from local
  values as changed (so they get sent out on save)
* properly reify parent values for onchange instead of sending them
  as-is
* the evaluation context for contexts (and domains) needs properly
  formatted values so use `_values_to_save` to get them, however it
  cares about neither required-ing nor filtering out e.g. unmodified
  fields, therefore add an awful toggle to handle this

Task 2150302

Probably todo in the future:

* better UI for change-tracking dict, should have "snapshot"
  support (to freeze / discard previous changes)
* cleanup save, it's unclear that it properly resets the form

closes odoo/odoo#43235

X-original-commit: 6c99fe3ffec3aeb8d210e3b943ccef81d62d44ce
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2020-01-13 16:24:17 +00:00
Xavier Morel a3371a467b [FIX] core: ask OS to pick CDT port
When running multiple odoo on the same machine (in order to test
multiple things concurrently, etc...) it's easily enough to start them
on 8069, 8070, 8071, ... and that *seems* to work, but then they start
walking on one another and *losing* chromes entirely, so you end up
with hundreds of chrome processes: right now with 2 Odoo running tests
my machine is at 365 Chrome processes, 550 process and 3180 threads
total (should be ~160 and ~700 with 2 chrome processes at most).

Instead, ask the OS to ask for a devtools port, then close the socket
and pass that to the child process. There's a race of sort for the
instant between closing the socket and Chrome reopening it, but:

* the window is very short
* we got a random port from the ephemeral range, it's possible
  somebody else gets it inbetween but unlikely (the 50% on a birthday
  attack is 200 for Linux's ephemeral range, it's a somewhat lower 150
  for the IANA range used by BSDs and Windows)

Sadly chrome doesn't stop if it can't bind to the port it's given.

closes odoo/odoo#42102

X-original-commit: 897ded1cb8b675024d75c6975ca171dbefdfc333
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2019-12-18 06:56:24 +00:00
Thibault Delavallée c3be4c3bc6 [IMP][MOV] mail: move / pimp test tools and asserts to mail
PURPOSE

Currently tools and asserts for mail tests are located inside test_mail
module. It makes difficult to re-use them in application tests or force them
to write custom quick and dirty tools and asserts. Purpose of this merge
is therefore to move tools classes and mocks to mail directly and use them
in various sub modules.

SPECIFICATIONS

Have class, mocks, tools and asserts available in mail so that all modules
below from mail can use them.

Including

  * mock mail gateway in a clean way: mock server connection, email building
    and sending;
  * allow to simulate errors while sending emails to test corner cases;
  * provide tools to insert emails in mail gateway;
  * mock mail application to check record creation (message, notifications,
    mails, ...);
  * mock bus notification;
  * provide clearer assert methods for bus and mail notifications;
  * provide clearer emails sending and content methods;
  * provide a with_user tool context manager for tests allowing to quickly
    change current user given a login;

Most of those tools, asserts and mocks come from test_mail/tests/common.py.
They have been partially rewritten to be easier to use or to perform tests
more cleanly.

Future commits will gradually update existing tests in test_mail, test_mass
mailing and test_mail_full.

LINKS

Task ID 2068986
PR #38070
2019-11-20 16:00:32 +00:00
Adrian Torres e0b5a0cdb6 [IMP] tests: use addCleanup and addClassCleanup where useful
This commit takes advantages of the features added in the parent commit
to have better/cleaner tests.

closes odoo/odoo#39368

Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
2019-11-07 08:30:59 +00:00
Adrian Torres ec587297eb [IMP] tests: partially backport classCleanups from CPython 3.8
This commit partially backports bpo-24412, which allows the definition of
class cleanups (addClassCleanup) and module cleanups (omitted),
similar to instance cleanups (addCleanup).

This is useful for tests that override unittest's setUpClass and
could crash during its execution: If this happens, it is possible that a
bunch of crap is left in the database or even worse, the cursor becomes
completely fucked; Thanks to the addClassCleanup, we can undo the damage
done by the setUpClass.

Another benefit is that it is called unconditionally after tearDownClass
is called, so it can also be called as a replacement and/or safer
tearDownClass.
2019-11-06 14:07:04 +00:00