See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 39 and 401]
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 /** 18 * Unit tests for backups cron helper. 19 * 20 * @package core_backup 21 * @category test 22 * @copyright 2012 Frédéric Massart <fred@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 namespace core_backup; 27 28 use backup; 29 use backup_cron_automated_helper; 30 31 defined('MOODLE_INTERNAL') || die(); 32 33 global $CFG; 34 require_once($CFG->dirroot . '/backup/util/helper/backup_cron_helper.class.php'); 35 require_once($CFG->dirroot . '/backup/util/interfaces/checksumable.class.php'); 36 require_once("$CFG->dirroot/backup/backup.class.php"); 37 38 /** 39 * Unit tests for backups cron helper. 40 * 41 * @package core_backup 42 * @category test 43 * @copyright 2012 Frédéric Massart <fred@moodle.com> 44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 45 */ 46 class cronhelper_test extends \advanced_testcase { 47 /** 48 * Test {@link backup_cron_automated_helper::calculate_next_automated_backup}. 49 */ 50 public function test_next_automated_backup() { 51 global $CFG; 52 53 $this->resetAfterTest(); 54 set_config('backup_auto_active', '1', 'backup'); 55 56 $this->setTimezone('Australia/Perth'); 57 58 // Notes 59 // - backup_auto_weekdays starts on Sunday 60 // - Tests cannot be done in the past 61 // - Only the DST on the server side is handled. 62 63 // Every Tue and Fri at 11pm. 64 set_config('backup_auto_weekdays', '0010010', 'backup'); 65 set_config('backup_auto_hour', '23', 'backup'); 66 set_config('backup_auto_minute', '0', 'backup'); 67 68 $timezone = 99; // Ignored, everything is calculated in server timezone!!! 69 70 $now = strtotime('next Monday 17:00:00'); 71 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 72 $this->assertEquals('2-23:00', date('w-H:i', $next)); 73 74 $now = strtotime('next Tuesday 18:00:00'); 75 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 76 $this->assertEquals('2-23:00', date('w-H:i', $next)); 77 78 $now = strtotime('next Wednesday 17:00:00'); 79 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 80 $this->assertEquals('5-23:00', date('w-H:i', $next)); 81 82 $now = strtotime('next Thursday 17:00:00'); 83 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 84 $this->assertEquals('5-23:00', date('w-H:i', $next)); 85 86 $now = strtotime('next Friday 17:00:00'); 87 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 88 $this->assertEquals('5-23:00', date('w-H:i', $next)); 89 90 $now = strtotime('next Saturday 17:00:00'); 91 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 92 $this->assertEquals('2-23:00', date('w-H:i', $next)); 93 94 $now = strtotime('next Sunday 17:00:00'); 95 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 96 $this->assertEquals('2-23:00', date('w-H:i', $next)); 97 98 // Every Sun and Sat at 12pm. 99 set_config('backup_auto_weekdays', '1000001', 'backup'); 100 set_config('backup_auto_hour', '0', 'backup'); 101 set_config('backup_auto_minute', '0', 'backup'); 102 103 $now = strtotime('next Monday 17:00:00'); 104 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 105 $this->assertEquals('6-00:00', date('w-H:i', $next)); 106 107 $now = strtotime('next Tuesday 17:00:00'); 108 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 109 $this->assertEquals('6-00:00', date('w-H:i', $next)); 110 111 $now = strtotime('next Wednesday 17:00:00'); 112 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 113 $this->assertEquals('6-00:00', date('w-H:i', $next)); 114 115 $now = strtotime('next Thursday 17:00:00'); 116 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 117 $this->assertEquals('6-00:00', date('w-H:i', $next)); 118 119 $now = strtotime('next Friday 17:00:00'); 120 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 121 $this->assertEquals('6-00:00', date('w-H:i', $next)); 122 123 $now = strtotime('next Saturday 17:00:00'); 124 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 125 $this->assertEquals('0-00:00', date('w-H:i', $next)); 126 127 $now = strtotime('next Sunday 17:00:00'); 128 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 129 $this->assertEquals('6-00:00', date('w-H:i', $next)); 130 131 // Every Sun at 4am. 132 set_config('backup_auto_weekdays', '1000000', 'backup'); 133 set_config('backup_auto_hour', '4', 'backup'); 134 set_config('backup_auto_minute', '0', 'backup'); 135 136 $now = strtotime('next Monday 17:00:00'); 137 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 138 $this->assertEquals('0-04:00', date('w-H:i', $next)); 139 140 $now = strtotime('next Tuesday 17:00:00'); 141 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 142 $this->assertEquals('0-04:00', date('w-H:i', $next)); 143 144 $now = strtotime('next Wednesday 17:00:00'); 145 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 146 $this->assertEquals('0-04:00', date('w-H:i', $next)); 147 148 $now = strtotime('next Thursday 17:00:00'); 149 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 150 $this->assertEquals('0-04:00', date('w-H:i', $next)); 151 152 $now = strtotime('next Friday 17:00:00'); 153 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 154 $this->assertEquals('0-04:00', date('w-H:i', $next)); 155 156 $now = strtotime('next Saturday 17:00:00'); 157 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 158 $this->assertEquals('0-04:00', date('w-H:i', $next)); 159 160 $now = strtotime('next Sunday 17:00:00'); 161 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 162 $this->assertEquals('0-04:00', date('w-H:i', $next)); 163 164 // Every day but Wed at 8:30pm. 165 set_config('backup_auto_weekdays', '1110111', 'backup'); 166 set_config('backup_auto_hour', '20', 'backup'); 167 set_config('backup_auto_minute', '30', 'backup'); 168 169 $now = strtotime('next Monday 17:00:00'); 170 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 171 $this->assertEquals('1-20:30', date('w-H:i', $next)); 172 173 $now = strtotime('next Tuesday 17:00:00'); 174 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 175 $this->assertEquals('2-20:30', date('w-H:i', $next)); 176 177 $now = strtotime('next Wednesday 17:00:00'); 178 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 179 $this->assertEquals('4-20:30', date('w-H:i', $next)); 180 181 $now = strtotime('next Thursday 17:00:00'); 182 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 183 $this->assertEquals('4-20:30', date('w-H:i', $next)); 184 185 $now = strtotime('next Friday 17:00:00'); 186 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 187 $this->assertEquals('5-20:30', date('w-H:i', $next)); 188 189 $now = strtotime('next Saturday 17:00:00'); 190 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 191 $this->assertEquals('6-20:30', date('w-H:i', $next)); 192 193 $now = strtotime('next Sunday 17:00:00'); 194 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 195 $this->assertEquals('0-20:30', date('w-H:i', $next)); 196 197 // Sun, Tue, Thu, Sat at 12pm. 198 set_config('backup_auto_weekdays', '1010101', 'backup'); 199 set_config('backup_auto_hour', '0', 'backup'); 200 set_config('backup_auto_minute', '0', 'backup'); 201 202 $now = strtotime('next Monday 13:00:00'); 203 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 204 $this->assertEquals('2-00:00', date('w-H:i', $next)); 205 206 $now = strtotime('next Tuesday 13:00:00'); 207 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 208 $this->assertEquals('4-00:00', date('w-H:i', $next)); 209 210 $now = strtotime('next Wednesday 13:00:00'); 211 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 212 $this->assertEquals('4-00:00', date('w-H:i', $next)); 213 214 $now = strtotime('next Thursday 13:00:00'); 215 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 216 $this->assertEquals('6-00:00', date('w-H:i', $next)); 217 218 $now = strtotime('next Friday 13:00:00'); 219 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 220 $this->assertEquals('6-00:00', date('w-H:i', $next)); 221 222 $now = strtotime('next Saturday 13:00:00'); 223 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 224 $this->assertEquals('0-00:00', date('w-H:i', $next)); 225 226 $now = strtotime('next Sunday 13:00:00'); 227 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 228 $this->assertEquals('2-00:00', date('w-H:i', $next)); 229 230 // None. 231 set_config('backup_auto_weekdays', '0000000', 'backup'); 232 set_config('backup_auto_hour', '15', 'backup'); 233 set_config('backup_auto_minute', '30', 'backup'); 234 235 $now = strtotime('next Sunday 13:00:00'); 236 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 237 $this->assertEquals('0', $next); 238 239 // Playing with timezones. 240 set_config('backup_auto_weekdays', '1111111', 'backup'); 241 set_config('backup_auto_hour', '20', 'backup'); 242 set_config('backup_auto_minute', '00', 'backup'); 243 244 $this->setTimezone('Australia/Perth'); 245 $now = strtotime('18:00:00'); 246 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 247 $this->assertEquals(date('w-20:00'), date('w-H:i', $next)); 248 249 $this->setTimezone('Europe/Brussels'); 250 $now = strtotime('18:00:00'); 251 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 252 $this->assertEquals(date('w-20:00'), date('w-H:i', $next)); 253 254 $this->setTimezone('America/New_York'); 255 $now = strtotime('18:00:00'); 256 $next = backup_cron_automated_helper::calculate_next_automated_backup($timezone, $now); 257 $this->assertEquals(date('w-20:00'), date('w-H:i', $next)); 258 } 259 260 /** 261 * Test {@link backup_cron_automated_helper::get_backups_to_delete}. 262 */ 263 public function test_get_backups_to_delete() { 264 $this->resetAfterTest(); 265 // Active only backup_auto_max_kept config to 2 days. 266 set_config('backup_auto_max_kept', '2', 'backup'); 267 set_config('backup_auto_delete_days', '0', 'backup'); 268 set_config('backup_auto_min_kept', '0', 'backup'); 269 270 // No backups to delete. 271 $backupfiles = array( 272 '1000000000' => 'file1.mbz', 273 '1000432000' => 'file3.mbz' 274 ); 275 $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000432000); 276 $this->assertFalse($deletedbackups); 277 278 // Older backup to delete. 279 $backupfiles['1000172800'] = 'file2.mbz'; 280 $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000432000); 281 $this->assertEquals(1, count($deletedbackups)); 282 $this->assertArrayHasKey('1000000000', $backupfiles); 283 $this->assertEquals('file1.mbz', $backupfiles['1000000000']); 284 285 // Activate backup_auto_max_kept to 5 days and backup_auto_delete_days to 10 days. 286 set_config('backup_auto_max_kept', '5', 'backup'); 287 set_config('backup_auto_delete_days', '10', 'backup'); 288 set_config('backup_auto_min_kept', '0', 'backup'); 289 290 // No backups to delete. Timestamp is 1000000000 + 10 days. 291 $backupfiles['1000432001'] = 'file4.mbz'; 292 $backupfiles['1000864000'] = 'file5.mbz'; 293 $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000864000); 294 $this->assertFalse($deletedbackups); 295 296 // One old backup to delete. Timestamp is 1000000000 + 10 days + 1 second. 297 $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1000864001); 298 $this->assertEquals(1, count($deletedbackups)); 299 $this->assertArrayHasKey('1000000000', $backupfiles); 300 $this->assertEquals('file1.mbz', $backupfiles['1000000000']); 301 302 // Two old backups to delete. Timestamp is 1000000000 + 12 days + 1 second. 303 $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1001036801); 304 $this->assertEquals(2, count($deletedbackups)); 305 $this->assertArrayHasKey('1000000000', $backupfiles); 306 $this->assertEquals('file1.mbz', $backupfiles['1000000000']); 307 $this->assertArrayHasKey('1000172800', $backupfiles); 308 $this->assertEquals('file2.mbz', $backupfiles['1000172800']); 309 310 // Activate backup_auto_max_kept to 5 days, backup_auto_delete_days to 10 days and backup_auto_min_kept to 2. 311 set_config('backup_auto_max_kept', '5', 'backup'); 312 set_config('backup_auto_delete_days', '10', 'backup'); 313 set_config('backup_auto_min_kept', '2', 'backup'); 314 315 // Three instead of four old backups are deleted. Timestamp is 1000000000 + 16 days. 316 $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1001382400); 317 $this->assertEquals(3, count($deletedbackups)); 318 $this->assertArrayHasKey('1000000000', $backupfiles); 319 $this->assertEquals('file1.mbz', $backupfiles['1000000000']); 320 $this->assertArrayHasKey('1000172800', $backupfiles); 321 $this->assertEquals('file2.mbz', $backupfiles['1000172800']); 322 $this->assertArrayHasKey('1000432000', $backupfiles); 323 $this->assertEquals('file3.mbz', $backupfiles['1000432000']); 324 325 // Three instead of all five backups are deleted. Timestamp is 1000000000 + 60 days. 326 $deletedbackups = testable_backup_cron_automated_helper::testable_get_backups_to_delete($backupfiles, 1005184000); 327 $this->assertEquals(3, count($deletedbackups)); 328 $this->assertArrayHasKey('1000000000', $backupfiles); 329 $this->assertEquals('file1.mbz', $backupfiles['1000000000']); 330 $this->assertArrayHasKey('1000172800', $backupfiles); 331 $this->assertEquals('file2.mbz', $backupfiles['1000172800']); 332 $this->assertArrayHasKey('1000432000', $backupfiles); 333 $this->assertEquals('file3.mbz', $backupfiles['1000432000']); 334 } 335 336 /** 337 * Test {@link backup_cron_automated_helper::is_course_modified}. 338 */ 339 public function test_is_course_modified() { 340 $this->resetAfterTest(); 341 $this->preventResetByRollback(); 342 343 set_config('enabled_stores', 'logstore_standard', 'tool_log'); 344 set_config('buffersize', 0, 'logstore_standard'); 345 set_config('logguests', 1, 'logstore_standard'); 346 347 $course = $this->getDataGenerator()->create_course(); 348 349 // New courses should be backed up. 350 $this->assertTrue(testable_backup_cron_automated_helper::testable_is_course_modified($course->id, 0)); 351 352 $timepriortobackup = time(); 353 $this->waitForSecond(); 354 $otherarray = [ 355 'format' => backup::FORMAT_MOODLE, 356 'mode' => backup::MODE_GENERAL, 357 'interactive' => backup::INTERACTIVE_YES, 358 'type' => backup::TYPE_1COURSE, 359 ]; 360 $event = \core\event\course_backup_created::create([ 361 'objectid' => $course->id, 362 'context' => \context_course::instance($course->id), 363 'other' => $otherarray 364 ]); 365 $event->trigger(); 366 367 // If the only action since last backup was a backup then no backup. 368 $this->assertFalse(testable_backup_cron_automated_helper::testable_is_course_modified($course->id, $timepriortobackup)); 369 370 $course->groupmode = SEPARATEGROUPS; 371 $course->groupmodeforce = true; 372 update_course($course); 373 374 // Updated courses should be backed up. 375 $this->assertTrue(testable_backup_cron_automated_helper::testable_is_course_modified($course->id, $timepriortobackup)); 376 } 377 378 /** 379 * Create courses and backup records for tests. 380 * 381 * @return array Created courses. 382 */ 383 private function course_setup() { 384 global $DB; 385 386 // Create test courses. 387 $course1 = $this->getDataGenerator()->create_course(array('timecreated' => 1553402000)); // Newest. 388 $course2 = $this->getDataGenerator()->create_course(array('timecreated' => 1552179600)); 389 $course3 = $this->getDataGenerator()->create_course(array('timecreated' => 1552179600)); 390 $course4 = $this->getDataGenerator()->create_course(array('timecreated' => 1552179600)); 391 392 // Create backup course records for the courses that need them. 393 $backupcourse3 = new \stdClass; 394 $backupcourse3->courseid = $course3->id; 395 $backupcourse3->laststatus = testable_backup_cron_automated_helper::BACKUP_STATUS_OK; 396 $backupcourse3->nextstarttime = 1554822160; 397 $DB->insert_record('backup_courses', $backupcourse3); 398 399 $backupcourse4 = new \stdClass; 400 $backupcourse4->courseid = $course4->id; 401 $backupcourse4->laststatus = testable_backup_cron_automated_helper::BACKUP_STATUS_OK; 402 $backupcourse4->nextstarttime = 1554858160; 403 $DB->insert_record('backup_courses', $backupcourse4); 404 405 return array($course1, $course2, $course3, $course4); 406 } 407 408 /** 409 * Test the selection and ordering of courses to be backed up. 410 */ 411 public function test_get_courses() { 412 $this->resetAfterTest(); 413 414 list($course1, $course2, $course3, $course4) = $this->course_setup(); 415 416 $now = 1559215025; 417 418 // Get the courses in order. 419 $courseset = testable_backup_cron_automated_helper::testable_get_courses($now); 420 421 $coursearray = array(); 422 foreach ($courseset as $course) { 423 if ($course->id != SITEID) { // Skip system course for test. 424 $coursearray[] = $course->id; 425 } 426 427 } 428 $courseset->close(); 429 430 // First should be course 1, it is the more recently modified without a backup. 431 $this->assertEquals($course1->id, $coursearray[0]); 432 433 // Second should be course 2, it is the next more recently modified without a backup. 434 $this->assertEquals($course2->id, $coursearray[1]); 435 436 // Third should be course 3, it is the course with the oldest backup. 437 $this->assertEquals($course3->id, $coursearray[2]); 438 439 // Fourth should be course 4, it is the course with the newest backup. 440 $this->assertEquals($course4->id, $coursearray[3]); 441 } 442 443 /** 444 * Test the selection and ordering of courses to be backed up. 445 * Where it is not yet time to start backups for courses with existing backups. 446 */ 447 public function test_get_courses_starttime() { 448 $this->resetAfterTest(); 449 450 list($course1, $course2, $course3, $course4) = $this->course_setup(); 451 452 $now = 1554858000; 453 454 // Get the courses in order. 455 $courseset = testable_backup_cron_automated_helper::testable_get_courses($now); 456 457 $coursearray = array(); 458 foreach ($courseset as $course) { 459 if ($course->id != SITEID) { // Skip system course for test. 460 $coursearray[] = $course->id; 461 } 462 463 } 464 $courseset->close(); 465 466 // Should only be two courses. 467 // First should be course 1, it is the more recently modified without a backup. 468 $this->assertEquals($course1->id, $coursearray[0]); 469 470 // Second should be course 2, it is the next more recently modified without a backup. 471 $this->assertEquals($course2->id, $coursearray[1]); 472 } 473 474 } 475 476 477 478 /** 479 * Provides access to protected methods we want to explicitly test 480 * 481 * @copyright 2015 Jean-Philippe Gaudreau <jp.gaudreau@umontreal.ca> 482 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 483 */ 484 class testable_backup_cron_automated_helper extends backup_cron_automated_helper { 485 486 /** 487 * Provides access to protected method get_backups_to_remove. 488 * 489 * @param array $backupfiles Existing backup files 490 * @param int $now Starting time of the process 491 * @return array Backup files to remove 492 */ 493 public static function testable_get_backups_to_delete($backupfiles, $now) { 494 return parent::get_backups_to_delete($backupfiles, $now); 495 } 496 497 /** 498 * Provides access to protected method get_backups_to_remove. 499 * 500 * @param int $courseid course id to check 501 * @param int $since timestamp, from which to check 502 * 503 * @return bool true if the course was modified, false otherwise. This also returns false if no readers are enabled. This is 504 * intentional, since we cannot reliably determine if any modification was made or not. 505 */ 506 public static function testable_is_course_modified($courseid, $since) { 507 return parent::is_course_modified($courseid, $since); 508 } 509 510 /** 511 * Provides access to protected method get_courses. 512 * 513 * @param int $now Timestamp to use. 514 * @return moodle_recordset The returned courses as a Moodle recordest. 515 */ 516 public static function testable_get_courses($now) { 517 return parent::get_courses($now); 518 } 519 520 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body