diff --git a/queue_job/job.py b/queue_job/job.py index e03dd2b517..208ce803d0 100644 --- a/queue_job/job.py +++ b/queue_job/job.py @@ -756,7 +756,7 @@ def db_record(self): @property def func(self): - recordset = self.recordset.with_context(job_uuid=self.uuid) + recordset = self.recordset.with_context(job_uuid=self.uuid, job_itself=self) return getattr(recordset, self.method_name) @property diff --git a/test_queue_job/models/test_models.py b/test_queue_job/models/test_models.py index ff9622106a..9e948322b5 100644 --- a/test_queue_job/models/test_models.py +++ b/test_queue_job/models/test_models.py @@ -5,7 +5,7 @@ from odoo.addons.queue_job.delay import chain from odoo.addons.queue_job.exception import RetryableJobError -from odoo.addons.queue_job.job import identity_exact +from odoo.addons.queue_job.job import Job, identity_exact class QueueJob(models.Model): @@ -139,6 +139,18 @@ def button_that_uses_delayable_chain(self): ) delayables.delay() + def child_job_from_ctx_job_uuid(self): + self._add_child_job(Job.load(self.env, self.env.context["job_uuid"])) + + def child_job_from_ctx_job_itself(self): + self._add_child_job(self.env.context["job_itself"]) + + def _add_child_job(self, parent_job): + child_job = self.with_delay().testing_method() + child_job.add_depends([parent_job]) + parent_job.store() + child_job.store() + class ModelTestQueueChannel(models.Model): _name = "test.queue.channel" diff --git a/test_queue_job/tests/test_dependencies.py b/test_queue_job/tests/test_dependencies.py index 4246fdbeba..58c658a6eb 100644 --- a/test_queue_job/tests/test_dependencies.py +++ b/test_queue_job/tests/test_dependencies.py @@ -5,6 +5,7 @@ from odoo.addons.queue_job.delay import DelayableGraph, chain, group from odoo.addons.queue_job.job import PENDING, WAIT_DEPENDENCIES, Job +from odoo.addons.queue_job.tests.common import trap_jobs class TestJobDependencies(common.TransactionCase): @@ -126,6 +127,38 @@ def test_depends_enqueue_waiting_single(self): # In practice, it won't be an issue for the jobrunner. self.assertEqual(Job.load(self.env, job_a.uuid).state, PENDING) + def _test_depends_on_running_job(self, job): + """Performs ``job`` and returns jobs spawned by its execution + + Mimics RunJobController._try_perform_job() + """ + job.set_started() + job.store() + with trap_jobs() as trap: + job.perform() + job.set_done() + job.store() + return trap.enqueued_jobs + + def test_depends_on_running_job_from_ctx_job_uuid(self): + job = self.env["test.queue.job"].with_delay().child_job_from_ctx_job_uuid() + child_jobs = self._test_depends_on_running_job(job) + self.assertEqual(len(child_jobs), 1) + child_job = child_jobs[0] + self.assertEqual({job}, child_job.depends_on) + self.assertIsNot(job, tuple(child_job.depends_on)[0]) + self.assertFalse(job.reverse_depends_on) + + def test_depends_on_running_job_from_ctx_job_itself(self): + job = self.env["test.queue.job"].with_delay().child_job_from_ctx_job_itself() + child_jobs = self._test_depends_on_running_job(job) + self.assertEqual(len(child_jobs), 1) + child_job = child_jobs[0] + self.assertEqual({job}, child_job.depends_on) + self.assertIs(job, tuple(child_job.depends_on)[0]) + self.assertEqual(job.reverse_depends_on, {child_job}) + self.assertIs(tuple(job.reverse_depends_on)[0], child_job) + def test_dependency_graph(self): job_root = Job(self.method) job_lvl1_a = Job(self.method) diff --git a/test_queue_job/tests/test_job.py b/test_queue_job/tests/test_job.py index 35884cd2b3..9b7d60536f 100644 --- a/test_queue_job/tests/test_job.py +++ b/test_queue_job/tests/test_job.py @@ -548,13 +548,14 @@ def test_wizard_requeue(self): model.create({}).requeue() self.assertEqual(stored.state, PENDING) - def test_context_uuid(self): + def test_context_job_data(self): delayable = self.env["test.queue.job"].with_delay() test_job = delayable.testing_method(return_context=True) result = test_job.perform() - key_present = "job_uuid" in result - self.assertTrue(key_present) + self.assertTrue("job_uuid" in result) self.assertEqual(result["job_uuid"], test_job._uuid) + self.assertTrue("job_itself" in result) + self.assertIs(result["job_itself"], test_job) def test_override_channel(self): delayable = self.env["test.queue.job"].with_delay(channel="root.sub.sub")