Differences Between: [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace core\task; 18 19 defined('MOODLE_INTERNAL') || die(); 20 require_once (__DIR__ . '/../fixtures/task_fixtures.php'); 21 22 23 /** 24 * Test class for adhoc tasks. 25 * 26 * @package core 27 * @category test 28 * @copyright 2013 Damyon Wiese 29 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 30 */ 31 class adhoc_task_test extends \advanced_testcase { 32 33 /** 34 * Test basic adhoc task execution. 35 */ 36 public function test_get_next_adhoc_task_now() { 37 $this->resetAfterTest(true); 38 39 // Create an adhoc task. 40 $task = new adhoc_test_task(); 41 42 // Queue it. 43 manager::queue_adhoc_task($task); 44 45 $now = time(); 46 // Get it from the scheduler. 47 $task = manager::get_next_adhoc_task($now); 48 $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task); 49 $task->execute(); 50 manager::adhoc_task_complete($task); 51 } 52 53 /** 54 * Test adhoc task failure retry backoff. 55 */ 56 public function test_get_next_adhoc_task_fail_retry() { 57 $this->resetAfterTest(true); 58 59 // Create an adhoc task. 60 $task = new adhoc_test_task(); 61 manager::queue_adhoc_task($task); 62 63 $now = time(); 64 65 // Get it from the scheduler, execute it, and mark it as failed. 66 $task = manager::get_next_adhoc_task($now); 67 $task->execute(); 68 manager::adhoc_task_failed($task); 69 70 // The task will not be returned immediately. 71 $this->assertNull(manager::get_next_adhoc_task($now)); 72 73 // Should get the adhoc task (retry after delay). 74 $task = manager::get_next_adhoc_task($now + 120); 75 $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task); 76 $task->execute(); 77 78 manager::adhoc_task_complete($task); 79 80 // Should not get any task. 81 $this->assertNull(manager::get_next_adhoc_task($now)); 82 } 83 84 /** 85 * Test future adhoc task execution. 86 */ 87 public function test_get_next_adhoc_task_future() { 88 $this->resetAfterTest(true); 89 90 $now = time(); 91 // Create an adhoc task in future. 92 $task = new adhoc_test_task(); 93 $task->set_next_run_time($now + 1000); 94 manager::queue_adhoc_task($task); 95 96 // Fetching the next task should not return anything. 97 $this->assertNull(manager::get_next_adhoc_task($now)); 98 99 // Fetching in the future should return the task. 100 $task = manager::get_next_adhoc_task($now + 1020); 101 $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task); 102 $task->execute(); 103 manager::adhoc_task_complete($task); 104 } 105 106 /** 107 * Test queueing an adhoc task belonging to a component, where we set the task component accordingly 108 */ 109 public function test_queue_adhoc_task_for_component(): void { 110 $this->resetAfterTest(); 111 112 $task = new \mod_forum\task\refresh_forum_post_counts(); 113 $task->set_component('mod_test'); 114 115 manager::queue_adhoc_task($task); 116 $this->assertDebuggingNotCalled(); 117 } 118 119 /** 120 * Test queueing an adhoc task belonging to a component, where we do not set the task component 121 */ 122 public function test_queue_task_for_component_without_set_component(): void { 123 $this->resetAfterTest(); 124 125 $task = new \mod_forum\task\refresh_forum_post_counts(); 126 127 manager::queue_adhoc_task($task); 128 $this->assertDebuggingNotCalled(); 129 130 // Assert the missing component was set. 131 $this->assertEquals('mod_forum', $task->get_component()); 132 } 133 134 /** 135 * Test queueing an adhoc task belonging to an invalid component, where we do not set the task component 136 */ 137 public function test_queue_task_for_invalid_component_without_set_component(): void { 138 $this->resetAfterTest(); 139 140 $task = new \mod_fake\task\adhoc_component_task(); 141 142 manager::queue_adhoc_task($task); 143 $this->assertDebuggingCalled('Component not set and the class namespace does not match a valid component (mod_fake).'); 144 } 145 146 /** 147 * Test empty set of adhoc tasks 148 */ 149 public function test_get_adhoc_tasks_empty_set() { 150 $this->resetAfterTest(true); 151 152 $this->assertEquals([], manager::get_adhoc_tasks('\\core\\task\\adhoc_test_task')); 153 } 154 155 /** 156 * Test correct set of adhoc tasks is returned for class. 157 */ 158 public function test_get_adhoc_tasks_result_set() { 159 $this->resetAfterTest(true); 160 161 for ($i = 0; $i < 3; $i++) { 162 $task = new adhoc_test_task(); 163 manager::queue_adhoc_task($task); 164 } 165 166 for ($i = 0; $i < 3; $i++) { 167 $task = new adhoc_test2_task(); 168 manager::queue_adhoc_task($task); 169 } 170 171 $adhoctests = manager::get_adhoc_tasks('\\core\\task\\adhoc_test_task'); 172 $adhoctest2s = manager::get_adhoc_tasks('\\core\\task\\adhoc_test2_task'); 173 174 $this->assertCount(3, $adhoctests); 175 $this->assertCount(3, $adhoctest2s); 176 177 foreach ($adhoctests as $task) { 178 $this->assertInstanceOf('\\core\\task\\adhoc_test_task', $task); 179 } 180 181 foreach ($adhoctest2s as $task) { 182 $this->assertInstanceOf('\\core\\task\\adhoc_test2_task', $task); 183 } 184 } 185 186 /** 187 * Ensure that the reschedule_or_queue_adhoc_task function will schedule a new task if no tasks exist. 188 */ 189 public function test_reschedule_or_queue_adhoc_task_no_existing() { 190 $this->resetAfterTest(true); 191 192 // Schedule adhoc task. 193 $task = new adhoc_test_task(); 194 $task->set_custom_data(['courseid' => 10]); 195 manager::reschedule_or_queue_adhoc_task($task); 196 $this->assertEquals(1, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 197 } 198 199 /** 200 * Ensure that the reschedule_or_queue_adhoc_task function will schedule a new task if a task for the same user does 201 * not exist. 202 */ 203 public function test_reschedule_or_queue_adhoc_task_different_user() { 204 $this->resetAfterTest(true); 205 $user = \core_user::get_user_by_username('admin'); 206 207 // Schedule adhoc task. 208 $task = new adhoc_test_task(); 209 $task->set_custom_data(['courseid' => 10]); 210 manager::reschedule_or_queue_adhoc_task($task); 211 212 // Schedule adhoc task for a different user. 213 $task = new adhoc_test_task(); 214 $task->set_custom_data(['courseid' => 10]); 215 $task->set_userid($user->id); 216 manager::reschedule_or_queue_adhoc_task($task); 217 218 $this->assertEquals(2, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 219 } 220 221 /** 222 * Ensure that the reschedule_or_queue_adhoc_task function will schedule a new task if a task with different custom 223 * data exists. 224 */ 225 public function test_reschedule_or_queue_adhoc_task_different_data() { 226 $this->resetAfterTest(true); 227 228 // Schedule adhoc task. 229 $task = new adhoc_test_task(); 230 $task->set_custom_data(['courseid' => 10]); 231 manager::reschedule_or_queue_adhoc_task($task); 232 233 // Schedule adhoc task for a different user. 234 $task = new adhoc_test_task(); 235 $task->set_custom_data(['courseid' => 11]); 236 manager::reschedule_or_queue_adhoc_task($task); 237 238 $this->assertEquals(2, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 239 } 240 241 /** 242 * Ensure that the reschedule_or_queue_adhoc_task function will not make any change for matching data if no time was 243 * specified. 244 */ 245 public function test_reschedule_or_queue_adhoc_task_match_no_change() { 246 $this->resetAfterTest(true); 247 248 // Schedule adhoc task. 249 $task = new adhoc_test_task(); 250 $task->set_custom_data(['courseid' => 10]); 251 $task->set_next_run_time(time() + DAYSECS); 252 manager::reschedule_or_queue_adhoc_task($task); 253 254 $before = manager::get_adhoc_tasks('core\task\adhoc_test_task'); 255 256 // Schedule the task again but do not specify a time. 257 $task = new adhoc_test_task(); 258 $task->set_custom_data(['courseid' => 10]); 259 manager::reschedule_or_queue_adhoc_task($task); 260 261 $this->assertEquals(1, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 262 $this->assertEquals($before, manager::get_adhoc_tasks('core\task\adhoc_test_task')); 263 } 264 265 /** 266 * Ensure that the reschedule_or_queue_adhoc_task function will update the run time if there are planned changes. 267 */ 268 public function test_reschedule_or_queue_adhoc_task_match_update_runtime() { 269 $this->resetAfterTest(true); 270 $initialruntime = time() + DAYSECS; 271 $newruntime = time() + WEEKSECS; 272 273 // Schedule adhoc task. 274 $task = new adhoc_test_task(); 275 $task->set_custom_data(['courseid' => 10]); 276 $task->set_next_run_time($initialruntime); 277 manager::reschedule_or_queue_adhoc_task($task); 278 279 $before = manager::get_adhoc_tasks('core\task\adhoc_test_task'); 280 281 // Schedule the task again. 282 $task = new adhoc_test_task(); 283 $task->set_custom_data(['courseid' => 10]); 284 $task->set_next_run_time($newruntime); 285 manager::reschedule_or_queue_adhoc_task($task); 286 287 $tasks = manager::get_adhoc_tasks('core\task\adhoc_test_task'); 288 $this->assertEquals(1, count($tasks)); 289 $this->assertNotEquals($before, $tasks); 290 $firsttask = reset($tasks); 291 $this->assertEquals($newruntime, $firsttask->get_next_run_time()); 292 } 293 294 /** 295 * Test queue_adhoc_task "if not scheduled". 296 */ 297 public function test_queue_adhoc_task_if_not_scheduled() { 298 $this->resetAfterTest(true); 299 $user = \core_user::get_user_by_username('admin'); 300 301 // Schedule adhoc task. 302 $task = new adhoc_test_task(); 303 $task->set_custom_data(array('courseid' => 10)); 304 $this->assertNotEmpty(manager::queue_adhoc_task($task, true)); 305 $this->assertEquals(1, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 306 307 // Schedule adhoc task with a user. 308 $task = new adhoc_test_task(); 309 $task->set_custom_data(array('courseid' => 10)); 310 $task->set_userid($user->id); 311 $this->assertNotEmpty(manager::queue_adhoc_task($task, true)); 312 $this->assertEquals(2, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 313 314 // Schedule same adhoc task with different custom data. 315 $task = new adhoc_test_task(); 316 $task->set_custom_data(array('courseid' => 1)); 317 $this->assertNotEmpty(manager::queue_adhoc_task($task, true)); 318 $this->assertEquals(3, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 319 320 // Schedule same adhoc task with same custom data. 321 $task = new adhoc_test_task(); 322 $task->set_custom_data(array('courseid' => 1)); 323 $this->assertEmpty(manager::queue_adhoc_task($task, true)); 324 $this->assertEquals(3, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 325 326 // Schedule same adhoc task with same custom data and a user. 327 $task = new adhoc_test_task(); 328 $task->set_custom_data(array('courseid' => 1)); 329 $task->set_userid($user->id); 330 $this->assertNotEmpty(manager::queue_adhoc_task($task, true)); 331 $this->assertEquals(4, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 332 333 // Schedule same adhoc task without custom data. 334 // Note: This task was created earlier. 335 $task = new adhoc_test_task(); 336 $this->assertNotEmpty(manager::queue_adhoc_task($task, true)); 337 $this->assertEquals(5, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 338 339 // Schedule same adhoc task without custom data (again). 340 $task5 = new adhoc_test_task(); 341 $this->assertEmpty(manager::queue_adhoc_task($task5, true)); 342 $this->assertEquals(5, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 343 344 // Schedule same adhoc task without custom data but with a userid. 345 $task6 = new adhoc_test_task(); 346 $user = \core_user::get_user_by_username('admin'); 347 $task6->set_userid($user->id); 348 $this->assertNotEmpty(manager::queue_adhoc_task($task6, true)); 349 $this->assertEquals(6, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 350 351 // Schedule same adhoc task again without custom data but with a userid. 352 $task6 = new adhoc_test_task(); 353 $user = \core_user::get_user_by_username('admin'); 354 $task6->set_userid($user->id); 355 $this->assertEmpty(manager::queue_adhoc_task($task6, true)); 356 $this->assertEquals(6, count(manager::get_adhoc_tasks('core\task\adhoc_test_task'))); 357 } 358 359 /** 360 * Test that when no userid is specified, it returns empty from the DB 361 * too. 362 */ 363 public function test_adhoc_task_user_empty() { 364 $this->resetAfterTest(true); 365 366 // Create an adhoc task in future. 367 $task = new adhoc_test_task(); 368 manager::queue_adhoc_task($task); 369 370 // Get it back from the scheduler. 371 $now = time(); 372 $task = manager::get_next_adhoc_task($now); 373 manager::adhoc_task_complete($task); 374 375 $this->assertEmpty($task->get_userid()); 376 } 377 378 /** 379 * Test that when a userid is specified, that userid is subsequently 380 * returned. 381 */ 382 public function test_adhoc_task_user_set() { 383 $this->resetAfterTest(true); 384 385 // Create an adhoc task in future. 386 $task = new adhoc_test_task(); 387 $user = \core_user::get_user_by_username('admin'); 388 $task->set_userid($user->id); 389 manager::queue_adhoc_task($task); 390 391 // Get it back from the scheduler. 392 $now = time(); 393 $task = manager::get_next_adhoc_task($now); 394 manager::adhoc_task_complete($task); 395 396 $this->assertEquals($user->id, $task->get_userid()); 397 } 398 399 /** 400 * Test get_concurrency_limit() method to return 0 by default. 401 */ 402 public function test_get_concurrency_limit() { 403 $this->resetAfterTest(true); 404 $task = new adhoc_test_task(); 405 $concurrencylimit = $task->get_concurrency_limit(); 406 $this->assertEquals(0, $concurrencylimit); 407 } 408 409 /** 410 * Test get_concurrency_limit() method to return a default value set in config. 411 */ 412 public function test_get_concurrency_limit_default() { 413 $this->resetAfterTest(true); 414 set_config('task_concurrency_limit_default', 10); 415 $task = new adhoc_test_task(); 416 $concurrencylimit = $task->get_concurrency_limit(); 417 $this->assertEquals(10, $concurrencylimit); 418 } 419 420 /** 421 * Test get_concurrency_limit() method to return a value for specific task class. 422 */ 423 public function test_get_concurrency_limit_for_task() { 424 global $CFG; 425 $this->resetAfterTest(true); 426 set_config('task_concurrency_limit_default', 10); 427 $CFG->task_concurrency_limit = array('core\task\adhoc_test_task' => 5); 428 $task = new adhoc_test_task(); 429 $concurrencylimit = $task->get_concurrency_limit(); 430 $this->assertEquals(5, $concurrencylimit); 431 } 432 433 /** 434 * Test adhoc task sorting. 435 */ 436 public function test_get_next_adhoc_task_sorting() { 437 $this->resetAfterTest(true); 438 439 // Create adhoc tasks. 440 $task1 = new adhoc_test_task(); 441 $task1->set_next_run_time(1510000000); 442 $task1->set_custom_data_as_string('Task 1'); 443 manager::queue_adhoc_task($task1); 444 445 $task2 = new adhoc_test_task(); 446 $task2->set_next_run_time(1520000000); 447 $task2->set_custom_data_as_string('Task 2'); 448 manager::queue_adhoc_task($task2); 449 450 $task3 = new adhoc_test_task(); 451 $task3->set_next_run_time(1520000000); 452 $task3->set_custom_data_as_string('Task 3'); 453 manager::queue_adhoc_task($task3); 454 455 // Shuffle tasks. 456 $task1->set_next_run_time(1540000000); 457 manager::reschedule_or_queue_adhoc_task($task1); 458 459 $task3->set_next_run_time(1530000000); 460 manager::reschedule_or_queue_adhoc_task($task3); 461 462 $task2->set_next_run_time(1530000000); 463 manager::reschedule_or_queue_adhoc_task($task2); 464 465 // Confirm, that tasks are sorted by nextruntime and then by id (ascending). 466 $task = manager::get_next_adhoc_task(time()); 467 $this->assertEquals('Task 2', $task->get_custom_data_as_string()); 468 manager::adhoc_task_complete($task); 469 470 $task = manager::get_next_adhoc_task(time()); 471 $this->assertEquals('Task 3', $task->get_custom_data_as_string()); 472 manager::adhoc_task_complete($task); 473 474 $task = manager::get_next_adhoc_task(time()); 475 $this->assertEquals('Task 1', $task->get_custom_data_as_string()); 476 manager::adhoc_task_complete($task); 477 } 478 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body