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