From eb694bdd5a687c235d0efbb7933f64fdae9649b3 Mon Sep 17 00:00:00 2001 From: Mikhail Golenkov Date: Tue, 22 Dec 2020 10:37:43 +1100 Subject: [PATCH 1/2] MDL-70520 tasks: Keep lastruntime when a scheduled task is reset --- lib/classes/task/manager.php | 1 + lib/tests/scheduled_task_test.php | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/classes/task/manager.php b/lib/classes/task/manager.php index 559c68f7676..0c28dd61726 100644 --- a/lib/classes/task/manager.php +++ b/lib/classes/task/manager.php @@ -229,6 +229,7 @@ class manager { $record = self::record_from_scheduled_task($task); $record->id = $original->id; $record->nextruntime = $task->get_next_scheduled_time(); + unset($record->lastruntime); $result = $DB->update_record('task_scheduled', $record); return $result; diff --git a/lib/tests/scheduled_task_test.php b/lib/tests/scheduled_task_test.php index a16e8e0bb48..aa03f51f59e 100644 --- a/lib/tests/scheduled_task_test.php +++ b/lib/tests/scheduled_task_test.php @@ -691,4 +691,24 @@ class core_scheduled_task_testcase extends advanced_testcase { call_user_func_array([$this, 'assertNotEquals'], $args); } + + /** + * Assert that the lastruntime column holds an original value after a scheduled task is reset. + */ + public function test_reset_scheduled_tasks_for_component_keeps_original_lastruntime(): void { + global $DB; + $this->resetAfterTest(true); + + // Set lastruntime for the scheduled task. + $DB->set_field('task_scheduled', 'lastruntime', 123456789, ['classname' => '\core\task\session_cleanup_task']); + + // Reset the task. + \core\task\manager::reset_scheduled_tasks_for_component('moodle'); + + // Fetch the task again. + $taskafterreset = \core\task\manager::get_scheduled_task(core\task\session_cleanup_task::class); + + // Confirm, that lastruntime is still in place. + $this->assertEquals(123456789, $taskafterreset->get_last_run_time()); + } } From c8229e391569432ce8b100b0fccf48a0a1909ce1 Mon Sep 17 00:00:00 2001 From: Mikhail Golenkov Date: Tue, 22 Dec 2020 12:57:17 +1100 Subject: [PATCH 2/2] MDL-70520 mod_assign: Use task API to get scheduled task lastruntime --- mod/assign/locallib.php | 3 +- mod/assign/tests/locallib_test.php | 50 ++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php index ce652aa9933..0697d541d13 100644 --- a/mod/assign/locallib.php +++ b/mod/assign/locallib.php @@ -2518,7 +2518,8 @@ class assign { // Only ever send a max of one days worth of updates. $yesterday = time() - (24 * 3600); $timenow = time(); - $lastruntime = $DB->get_field('task_scheduled', 'lastruntime', array('component' => 'mod_assign')); + $task = \core\task\manager::get_scheduled_task(mod_assign\task\cron_task::class); + $lastruntime = $task->get_last_run_time(); // Collect all submissions that require mailing. // Submissions are included if all are true: diff --git a/mod/assign/tests/locallib_test.php b/mod/assign/tests/locallib_test.php index 8c51acbebc1..0d5af67cdc5 100644 --- a/mod/assign/tests/locallib_test.php +++ b/mod/assign/tests/locallib_test.php @@ -4206,4 +4206,54 @@ Anchor link 2:Link text $output3 .= $assign->get_renderer()->render($summary); $this->assertStringContainsStringIgnoringCase('Friday, 7 June 2019, 5:37 PM', $output3); } + + /** + * Test that cron task uses task API to get its last run time. + */ + public function test_cron_use_task_api_to_get_lastruntime() { + global $DB; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + + // Create an assignment which allows submissions from 3 days ago. + $assign1 = $this->create_instance($course, [ + 'duedate' => time() + DAYSECS, + 'alwaysshowdescription' => 0, + 'allowsubmissionsfromdate' => time() - 3 * DAYSECS, + 'intro' => 'This one should not be re-created', + ]); + + // Create an assignment which allows submissions from 1 day ago. + $assign2 = $this->create_instance($course, [ + 'duedate' => time() + DAYSECS, + 'alwaysshowdescription' => 0, + 'allowsubmissionsfromdate' => time() - DAYSECS, + 'intro' => 'This one should be re-created', + ]); + + // Set last run time 2 days ago. + $DB->set_field('task_scheduled', 'lastruntime', time() - 2 * DAYSECS, ['classname' => '\mod_assign\task\cron_task']); + + // Remove events to make sure cron will update calendar and re-create one of them. + $params = array('modulename' => 'assign', 'instance' => $assign1->get_instance()->id); + $DB->delete_records('event', $params); + $params = array('modulename' => 'assign', 'instance' => $assign2->get_instance()->id); + $DB->delete_records('event', $params); + + // Run cron. + assign::cron(); + + // Assert that calendar hasn't been updated for the first assignment as it's supposed to be + // updated as part of previous cron runs (allowsubmissionsfromdate is less than lastruntime). + $params = array('modulename' => 'assign', 'instance' => $assign1->get_instance()->id); + $event1 = $DB->get_record('event', $params); + $this->assertEmpty($event1); + + // Assert that calendar has been updated for the second assignment + // because its allowsubmissionsfromdate is greater than lastruntime. + $params = array('modulename' => 'assign', 'instance' => $assign2->get_instance()->id); + $event2 = $DB->get_record('event', $params); + $this->assertNotEmpty($event2); + $this->assertSame('This one should be re-created', $event2->description); + } }