diff --git a/lib/classes/task/manager.php b/lib/classes/task/manager.php index a06a4517b49..95cbcfcdf56 100644 --- a/lib/classes/task/manager.php +++ b/lib/classes/task/manager.php @@ -135,8 +135,10 @@ class manager { global $DB; $record = self::record_from_adhoc_task($task); - // Schedule it immediately. - $record->nextruntime = time() - 1; + // Schedule it immediately if nextruntime not explicitly set. + if (!$task->get_next_run_time()) { + $record->nextruntime = time() - 1; + } $result = $DB->insert_record('task_adhoc', $record); return $result; diff --git a/lib/tests/adhoc_task_test.php b/lib/tests/adhoc_task_test.php index 174e54c2852..1c4d70a0628 100644 --- a/lib/tests/adhoc_task_test.php +++ b/lib/tests/adhoc_task_test.php @@ -37,34 +37,76 @@ require_once(__DIR__ . '/fixtures/task_fixtures.php'); */ class core_adhoc_task_testcase extends advanced_testcase { - public function test_get_next_adhoc_task() { + /** + * Test basic adhoc task execution. + */ + public function test_get_next_adhoc_task_now() { $this->resetAfterTest(true); + // Create an adhoc task. $task = new \core\task\adhoc_test_task(); // Queue it. - $task = \core\task\manager::queue_adhoc_task($task); + \core\task\manager::queue_adhoc_task($task); $now = time(); // Get it from the scheduler. $task = \core\task\manager::get_next_adhoc_task($now); - $this->assertNotNull($task); + $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task); $task->execute(); + \core\task\manager::adhoc_task_complete($task); + } - \core\task\manager::adhoc_task_failed($task); - // Should not get any task. + /** + * Test adhoc task failure retry backoff. + */ + public function test_get_next_adhoc_task_fail_retry() { + $this->resetAfterTest(true); + + // Create an adhoc task. + $task = new \core\task\adhoc_test_task(); + \core\task\manager::queue_adhoc_task($task); + + $now = time(); + + // Get it from the scheduler, execute it, and mark it as failed. $task = \core\task\manager::get_next_adhoc_task($now); - $this->assertNull($task); + $task->execute(); + \core\task\manager::adhoc_task_failed($task); + + // The task will not be returned immediately. + $this->assertNull(\core\task\manager::get_next_adhoc_task($now)); // Should get the adhoc task (retry after delay). $task = \core\task\manager::get_next_adhoc_task($now + 120); - $this->assertNotNull($task); + $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task); $task->execute(); \core\task\manager::adhoc_task_complete($task); // Should not get any task. - $task = \core\task\manager::get_next_adhoc_task($now); - $this->assertNull($task); + $this->assertNull(\core\task\manager::get_next_adhoc_task($now)); + } + + /** + * Test future adhoc task execution. + */ + public function test_get_next_adhoc_task_future() { + $this->resetAfterTest(true); + + $now = time(); + // Create an adhoc task in future. + $task = new \core\task\adhoc_test_task(); + $task->set_next_run_time($now + 1000); + \core\task\manager::queue_adhoc_task($task); + + // Fetching the next task should not return anything. + $this->assertNull(\core\task\manager::get_next_adhoc_task($now)); + + // Fetching in the future should return the task. + $task = \core\task\manager::get_next_adhoc_task($now + 1020); + $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task); + $task->execute(); + \core\task\manager::adhoc_task_complete($task); } }