This addon adds an integrated Job Queue to Odoo.
@@ -928,21 +928,7 @@
@@ -1008,8 +994,8 @@
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
-
Current maintainer:
-

+
Current maintainers:
+

This module is part of the OCA/queue project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/queue_job/tests/test_wizards.py b/queue_job/tests/test_wizards.py
index 2ac162d313..7738836d2f 100644
--- a/queue_job/tests/test_wizards.py
+++ b/queue_job/tests/test_wizards.py
@@ -46,3 +46,60 @@ def test_03_done(self):
wizard = self._wizard("queue.jobs.to.done")
wizard.set_done()
self.assertEqual(self.job.state, "done")
+
+ def test_04_requeue_forbidden(self):
+ wizard = self._wizard("queue.requeue.job")
+
+ # State WAIT_DEPENDENCIES is not requeued
+ self.job.state = "wait_dependencies"
+ wizard.requeue()
+ self.assertEqual(self.job.state, "wait_dependencies")
+
+ # State PENDING, ENQUEUED or STARTED are ignored too
+ for test_state in ("pending", "enqueued", "started"):
+ self.job.state = test_state
+ wizard.requeue()
+ self.assertEqual(self.job.state, test_state)
+
+ # States CANCELLED, DONE or FAILED will change status
+ self.job.state = "cancelled"
+ wizard.requeue()
+ self.assertEqual(self.job.state, "pending")
+
+ def test_05_cancel_forbidden(self):
+ wizard = self._wizard("queue.jobs.to.cancelled")
+
+ # State WAIT_DEPENDENCIES is not cancelled
+ self.job.state = "wait_dependencies"
+ wizard.set_cancelled()
+ self.assertEqual(self.job.state, "wait_dependencies")
+
+ # State DONE is not cancelled
+ self.job.state = "done"
+ wizard.set_cancelled()
+ self.assertEqual(self.job.state, "done")
+
+ # State PENDING, ENQUEUED or FAILED will be cancelled
+ for test_state in ("pending", "enqueued"):
+ self.job.state = test_state
+ wizard.set_cancelled()
+ self.assertEqual(self.job.state, "cancelled")
+
+ def test_06_done_forbidden(self):
+ wizard = self._wizard("queue.jobs.to.done")
+
+ # State STARTED is not set DONE manually
+ self.job.state = "started"
+ wizard.set_done()
+ self.assertEqual(self.job.state, "started")
+
+ # State CANCELLED is not cancelled
+ self.job.state = "cancelled"
+ wizard.set_done()
+ self.assertEqual(self.job.state, "cancelled")
+
+ # State WAIT_DEPENDENCIES, PENDING, ENQUEUED or FAILED will be set to DONE
+ for test_state in ("wait_dependencies", "pending", "enqueued"):
+ self.job.state = test_state
+ wizard.set_done()
+ self.assertEqual(self.job.state, "done")
diff --git a/queue_job/wizards/queue_jobs_to_cancelled.py b/queue_job/wizards/queue_jobs_to_cancelled.py
index 9e73374ebd..bb9f831576 100644
--- a/queue_job/wizards/queue_jobs_to_cancelled.py
+++ b/queue_job/wizards/queue_jobs_to_cancelled.py
@@ -10,8 +10,8 @@ class SetJobsToCancelled(models.TransientModel):
_description = "Cancel all selected jobs"
def set_cancelled(self):
- jobs = self.job_ids.filtered(
- lambda x: x.state in ("pending", "failed", "enqueued")
- )
+ # Only jobs with state PENDING, FAILED, ENQUEUED
+ # will change to CANCELLED
+ jobs = self.job_ids
jobs.button_cancelled()
return {"type": "ir.actions.act_window_close"}
diff --git a/queue_job/wizards/queue_jobs_to_done.py b/queue_job/wizards/queue_jobs_to_done.py
index ff1366ffed..caf8129213 100644
--- a/queue_job/wizards/queue_jobs_to_done.py
+++ b/queue_job/wizards/queue_jobs_to_done.py
@@ -10,6 +10,8 @@ class SetJobsToDone(models.TransientModel):
_description = "Set all selected jobs to done"
def set_done(self):
+ # Only jobs with state WAIT_DEPENDENCIES, PENDING, ENQUEUED or FAILED
+ # will change to DONE
jobs = self.job_ids
jobs.button_done()
return {"type": "ir.actions.act_window_close"}
diff --git a/queue_job/wizards/queue_requeue_job.py b/queue_job/wizards/queue_requeue_job.py
index 67d2ffcbdc..a88256300f 100644
--- a/queue_job/wizards/queue_requeue_job.py
+++ b/queue_job/wizards/queue_requeue_job.py
@@ -20,6 +20,7 @@ def _default_job_ids(self):
)
def requeue(self):
+ # Only jobs with state FAILED, DONE or CANCELLED will change to PENDING
jobs = self.job_ids
jobs.requeue()
return {"type": "ir.actions.act_window_close"}
diff --git a/test_queue_job/__manifest__.py b/test_queue_job/__manifest__.py
index 1a844dcd39..8e80ab2ced 100644
--- a/test_queue_job/__manifest__.py
+++ b/test_queue_job/__manifest__.py
@@ -3,7 +3,7 @@
{
"name": "Queue Job Tests",
- "version": "18.0.2.0.0",
+ "version": "18.0.2.0.1",
"author": "Camptocamp,Odoo Community Association (OCA)",
"license": "LGPL-3",
"category": "Generic Modules",
@@ -15,5 +15,6 @@
"security/ir.model.access.csv",
"data/queue_job_test_job.xml",
],
+ "maintainers": ["sbidoul"],
"installable": True,
}
diff --git a/test_queue_job/tests/test_requeue_dead_job.py b/test_queue_job/tests/test_requeue_dead_job.py
index a6328fed76..58890adf24 100644
--- a/test_queue_job/tests/test_requeue_dead_job.py
+++ b/test_queue_job/tests/test_requeue_dead_job.py
@@ -99,3 +99,19 @@ def test_requeue_dead_jobs(self):
uuids_requeued = self.env.cr.fetchall()
self.assertTrue(queue_job.uuid in j[0] for j in uuids_requeued)
+
+ def test_requeue_orphaned_jobs(self):
+ queue_job = self._get_demo_job("test_enqueued_job")
+ job_obj = Job.load(self.env, queue_job.uuid)
+
+ # Only enqueued job, don't set it to started to simulate the scenario
+ # that system shutdown before job is starting
+ job_obj.set_enqueued()
+ job_obj.date_enqueued = datetime.now() - timedelta(minutes=1)
+ job_obj.store()
+
+ # job is now picked up by the requeue query (which includes orphaned jobs)
+ query = Database(self.env.cr.dbname)._query_requeue_dead_jobs()
+ self.env.cr.execute(query)
+ uuids_requeued = self.env.cr.fetchall()
+ self.assertTrue(queue_job.uuid in j[0] for j in uuids_requeued)