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