Skip to content

Commit

Permalink
Merge PR #680 into 14.0
Browse files Browse the repository at this point in the history
Signed-off-by simahawk
  • Loading branch information
OCA-git-bot committed Sep 4, 2024
2 parents 30e57e6 + 21f6e25 commit 03ca33d
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 34 deletions.
9 changes: 5 additions & 4 deletions queue_job/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -408,13 +408,14 @@ Example:
When you are developing (ie: connector modules) you might want
to bypass the queue job and run your code immediately.

To do so you can set `TEST_QUEUE_JOB_NO_DELAY=1` in your enviroment.
To do so you can set `QUEUE_JOB_NO_DELAY=1` in your enviroment.

**Bypass jobs in tests**

When writing tests on job-related methods is always tricky to deal with
delayed recordsets. To make your testing life easier
you can set `test_queue_job_no_delay=True` in the context.
delayed recordsets. To make your testing life easier,
or to run a delayed action immediately,
you can set `queue_job__no_delay=True` in the context.

Tip: you can do this at test case level like this

Expand All @@ -425,7 +426,7 @@ Tip: you can do this at test case level like this
super().setUpClass()
cls.env = cls.env(context=dict(
cls.env.context,
test_queue_job_no_delay=True, # no jobs thanks
queue_job__no_delay=True, # no jobs thanks
))
Then all your tests execute the job methods synchronously
Expand Down
12 changes: 2 additions & 10 deletions queue_job/delay.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

import itertools
import logging
import os
import uuid
from collections import defaultdict, deque

from .job import Job
from .utils import must_run_without_delay

_logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -217,17 +217,9 @@ def _has_to_execute_directly(self, vertices):
In tests, prefer to use
:func:`odoo.addons.queue_job.tests.common.trap_jobs`.
"""
if os.getenv("TEST_QUEUE_JOB_NO_DELAY"):
_logger.warning(
"`TEST_QUEUE_JOB_NO_DELAY` env var found. NO JOB scheduled."
)
return True
envs = {vertex.recordset.env for vertex in vertices}
for env in envs:
if env.context.get("test_queue_job_no_delay"):
_logger.warning(
"`test_queue_job_no_delay` ctx key found." " NO JOB scheduled."
)
if must_run_without_delay(env):
return True
return False

Expand Down
7 changes: 2 additions & 5 deletions queue_job/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)

import functools
import logging

from odoo import api, models

from ..delay import Delayable
from ..job import DelayableRecordset

_logger = logging.getLogger(__name__)
from ..utils import must_run_without_delay


class Base(models.AbstractModel):
Expand Down Expand Up @@ -216,8 +214,7 @@ def auto_delay_wrapper(self, *args, **kwargs):
if (
self.env.context.get("job_uuid")
or not context_delay
or self.env.context.get("_job_force_sync")
or self.env.context.get("test_queue_job_no_delay")
or must_run_without_delay(self.env)
):
# we are in the job execution
return auto_delay_wrapper.origin(self, *args, **kwargs)
Expand Down
14 changes: 7 additions & 7 deletions queue_job/readme/USAGE.rst
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,13 @@ Example:
When you are developing (ie: connector modules) you might want
to bypass the queue job and run your code immediately.

To do so you can set `TEST_QUEUE_JOB_NO_DELAY=1` in your enviroment.
To do so you can set `QUEUE_JOB__NO_DELAY=1` in your enviroment.

**Bypass jobs in tests**

When writing tests on job-related methods is always tricky to deal with
delayed recordsets. To make your testing life easier
you can set `test_queue_job_no_delay=True` in the context.
you can set `queue_job__no_delay=True` in the context.

Tip: you can do this at test case level like this

Expand All @@ -288,7 +288,7 @@ Tip: you can do this at test case level like this
super().setUpClass()
cls.env = cls.env(context=dict(
cls.env.context,
test_queue_job_no_delay=True, # no jobs thanks
queue_job__no_delay=True, # no jobs thanks
))
Then all your tests execute the job methods synchronously
Expand Down Expand Up @@ -393,15 +393,15 @@ If you prefer, you can still test the whole thing in a single test, by calling
When you are developing (ie: connector modules) you might want
to bypass the queue job and run your code immediately.
To do so you can set ``TEST_QUEUE_JOB_NO_DELAY=1`` in your environment.
To do so you can set ``QUEUE_JOB__NO_DELAY=1`` in your environment.
.. WARNING:: Do not do this in production
**Execute jobs synchronously in tests**
You should use ``trap_jobs``, really, but if for any reason you could not use it,
and still need to have job methods executed synchronously in your tests, you can
do so by setting ``test_queue_job_no_delay=True`` in the context.
do so by setting ``queue_job__no_delay=True`` in the context.
Tip: you can do this at test case level like this
Expand All @@ -412,7 +412,7 @@ Tip: you can do this at test case level like this
super().setUpClass()
cls.env = cls.env(context=dict(
cls.env.context,
test_queue_job_no_delay=True, # no jobs thanks
queue_job__no_delay=True, # no jobs thanks
))
Then all your tests execute the job methods synchronously without delaying any
Expand All @@ -422,7 +422,7 @@ In tests you'll have to mute the logger like:
@mute_logger('odoo.addons.queue_job.models.base')
.. NOTE:: in graphs of jobs, the ``test_queue_job_no_delay`` context key must be in at
.. NOTE:: in graphs of jobs, the ``queue_job__no_delay`` context key must be in at
least one job's env of the graph for the whole graph to be executed synchronously
Expand Down
40 changes: 40 additions & 0 deletions queue_job/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2023 Camptocamp
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html)

import logging
import os

_logger = logging.getLogger(__name__)


def must_run_without_delay(env):
"""Retrun true if jobs have to run immediately.
:param env: `odoo.api.Environment` instance
"""
# TODO: drop in v17
if os.getenv("TEST_QUEUE_JOB_NO_DELAY"):
_logger.warning(
"`TEST_QUEUE_JOB_NO_DELAY` env var found. NO JOB scheduled. "
"Note that this key is deprecated: please use `QUEUE_JOB__NO_DELAY`"
)
return True

if os.getenv("QUEUE_JOB__NO_DELAY"):
_logger.warning("`QUEUE_JOB__NO_DELAY` env var found. NO JOB scheduled.")
return True

# TODO: drop in v17
deprecated_keys = ("_job_force_sync", "test_queue_job_no_delay")
for key in deprecated_keys:
if env.context.get(key):
_logger.warning(
"`%s` ctx key found. NO JOB scheduled. "
"Note that this key is deprecated: please use `queue_job__no_delay`",
key,
)
return True

if env.context.get("queue_job__no_delay"):
_logger.warning("`queue_job__no_delay` ctx key found. NO JOB scheduled.")
return True
16 changes: 8 additions & 8 deletions test_queue_job/tests/test_delay_mocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ def test_mock_with_delay(self):
self.assertEqual(delay_args, (1,))
self.assertDictEqual(delay_kwargs, {"foo": 2})

@mute_logger("odoo.addons.queue_job.models.base")
@mock.patch.dict(os.environ, {"TEST_QUEUE_JOB_NO_DELAY": "1"})
@mute_logger("odoo.addons.queue_job.utils")
@mock.patch.dict(os.environ, {"QUEUE_JOB__NO_DELAY": "1"})
def test_delay_graph_direct_exec_env_var(self):
node = Delayable(self.env["test.queue.job"]).create_ir_logging(
"test_delay_graph_direct_exec 1"
Expand All @@ -318,10 +318,10 @@ def test_delay_graph_direct_exec_env_var(self):
self.assertEqual(logs[0].message, "test_delay_graph_direct_exec 2")
self.assertEqual(logs[1].message, "test_delay_graph_direct_exec 1")

@mute_logger("odoo.addons.queue_job.models.base")
@mute_logger("odoo.addons.queue_job.utils")
def test_delay_graph_direct_exec_context_key(self):
node = Delayable(
self.env["test.queue.job"].with_context(test_queue_job_no_delay=True)
self.env["test.queue.job"].with_context(queue_job__no_delay=True)
).create_ir_logging("test_delay_graph_direct_exec 1")
node2 = Delayable(self.env["test.queue.job"]).create_ir_logging(
"test_delay_graph_direct_exec 2"
Expand All @@ -341,8 +341,8 @@ def test_delay_graph_direct_exec_context_key(self):
self.assertEqual(logs[0].message, "test_delay_graph_direct_exec 2")
self.assertEqual(logs[1].message, "test_delay_graph_direct_exec 1")

@mute_logger("odoo.addons.queue_job.models.base")
@mock.patch.dict(os.environ, {"TEST_QUEUE_JOB_NO_DELAY": "1"})
@mute_logger("odoo.addons.queue_job.utils")
@mock.patch.dict(os.environ, {"QUEUE_JOB__NO_DELAY": "1"})
def test_delay_with_delay_direct_exec_env_var(self):
model = self.env["test.queue.job"]
model.with_delay().create_ir_logging("test_delay_graph_direct_exec 1")
Expand All @@ -357,9 +357,9 @@ def test_delay_with_delay_direct_exec_env_var(self):
self.assertEqual(len(logs), 1)
self.assertEqual(logs[0].message, "test_delay_graph_direct_exec 1")

@mute_logger("odoo.addons.queue_job.models.base")
@mute_logger("odoo.addons.queue_job.utils")
def test_delay_with_delay_direct_exec_context_key(self):
model = self.env["test.queue.job"].with_context(test_queue_job_no_delay=True)
model = self.env["test.queue.job"].with_context(queue_job__no_delay=True)
model.with_delay().create_ir_logging("test_delay_graph_direct_exec 1")
# jobs are executed directly
logs = self.env["ir.logging"].search(
Expand Down

0 comments on commit 03ca33d

Please sign in to comment.