Rev 1 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>./*** Automated backup tests.** @package core_backup* @copyright 2019 John Yao <johnyao@catalyst-au.net>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/namespace core_backup;use backup_cron_automated_helper;defined('MOODLE_INTERNAL') || die();global $CFG;require_once($CFG->dirroot . '/backup/util/helper/backup_cron_helper.class.php');require_once($CFG->libdir . '/completionlib.php');/*** Automated backup tests.** @package core_backup* @copyright 2019 John Yao <johnyao@catalyst-au.net>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class automated_backup_test extends \advanced_testcase {/*** @var \backup_cron_automated_helper*/protected $backupcronautomatedhelper;/*** @var \stdClass $course*/protected $course;protected function setUp(): void {global $DB, $CFG;$this->resetAfterTest(true);$this->setAdminUser();$CFG->enableavailability = true;$CFG->enablecompletion = true;// Getting a testable backup_cron_automated_helper class.$this->backupcronautomatedhelper = new test_backup_cron_automated_helper();$generator = $this->getDataGenerator();$this->course = $generator->create_course(array('format' => 'topics', 'numsections' => 3,'enablecompletion' => COMPLETION_ENABLED),array('createsections' => true));$forum = $generator->create_module('forum', array('course' => $this->course->id));$forum2 = $generator->create_module('forum', array('course' => $this->course->id, 'completion' => COMPLETION_TRACKING_MANUAL));// We need a grade, easiest is to add an assignment.$assignrow = $generator->create_module('assign', array('course' => $this->course->id));$assign = new \assign(\context_module::instance($assignrow->cmid), false, false);$item = $assign->get_grade_item();// Make a test grouping as well.$grouping = $generator->create_grouping(array('courseid' => $this->course->id,'name' => 'Grouping!'));$availability = '{"op":"|","show":false,"c":[' .'{"type":"completion","cm":' . $forum2->cmid .',"e":1},' .'{"type":"grade","id":' . $item->id . ',"min":4,"max":94},' .'{"type":"grouping","id":' . $grouping->id . '}' .']}';$DB->set_field('course_modules', 'availability', $availability, array('id' => $forum->cmid));$DB->set_field('course_sections', 'availability', $availability, array('course' => $this->course->id, 'section' => 1));}/*** Tests the automated backup run when the there is course backup should be skipped.*/public function test_automated_backup_skipped_run(): void {global $DB;// Enable automated back up.set_config('backup_auto_active', true, 'backup');set_config('backup_auto_weekdays', '1111111', 'backup');// Start backup process.$admin = get_admin();// Backup entry should not exist.$backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));$this->assertFalse($backupcourse);$this->assertInstanceOf(backup_cron_automated_helper::class,$this->backupcronautomatedhelper->return_this());$classobject = $this->backupcronautomatedhelper->return_this();$method = new \ReflectionMethod('\backup_cron_automated_helper', 'get_courses');$courses = $method->invoke($classobject);$method = new \ReflectionMethod('\backup_cron_automated_helper', 'check_and_push_automated_backups');$emailpending = $method->invokeArgs($classobject, [$courses, $admin]);$this->expectOutputRegex('/Skipping course id ' . $this->course->id . ': Not scheduled for backup until/');$this->assertFalse($emailpending);$backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));$this->assertNotNull($backupcourse->laststatus);}/*** Tests the automated backup run when the there is course backup can be pushed to adhoc task.*/public function test_automated_backup_push_run(): void {global $DB;// Enable automated back up.set_config('backup_auto_active', true, 'backup');set_config('backup_auto_weekdays', '1111111', 'backup');$admin = get_admin();$classobject = $this->backupcronautomatedhelper->return_this();$method = new \ReflectionMethod('\backup_cron_automated_helper', 'get_courses');$courses = $method->invoke($classobject);// Create this backup course.$backupcourse = new \stdClass;$backupcourse->courseid = $this->course->id;$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_NOTYETRUN;$DB->insert_record('backup_courses', $backupcourse);$backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));// We now manually trigger a backup pushed to adhoc task.// Make sure is in the past, which means should run now.$backupcourse->nextstarttime = time() - 10;$DB->update_record('backup_courses', $backupcourse);$method = new \ReflectionMethod('\backup_cron_automated_helper', 'check_and_push_automated_backups');$emailpending = $method->invokeArgs($classobject, [$courses, $admin]);$this->assertTrue($emailpending);$this->expectOutputRegex('/Putting backup of course id ' . $this->course->id. ' in adhoc task queue/');$backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));// Now this backup course status should be queued.$this->assertEquals(backup_cron_automated_helper::BACKUP_STATUS_QUEUED, $backupcourse->laststatus);}/*** Tests the automated backup inactive run.*/public function test_inactive_run(): void {backup_cron_automated_helper::run_automated_backup();$this->expectOutputString("Checking automated backup status...INACTIVE\n");}/*** Tests the invisible course being skipped.*/public function test_should_skip_invisible_course(): void {global $DB;set_config('backup_auto_active', true, 'backup');set_config('backup_auto_skip_hidden', true, 'backup');set_config('backup_auto_weekdays', '1111111', 'backup');// Create this backup course.$backupcourse = new \stdClass;$backupcourse->courseid = $this->course->id;// This is the status we believe last run was OK.$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;$DB->insert_record('backup_courses', $backupcourse);$backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));$this->assertTrue(course_change_visibility($this->course->id, false));$course = $DB->get_record('course', array('id' => $this->course->id));$this->assertEquals('0', $course->visible);$classobject = $this->backupcronautomatedhelper->return_this();$nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time());$method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup');$skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]);$this->assertTrue($skipped);$this->expectOutputRegex('/Skipping course id ' . $this->course->id. ': Not visible/');}/*** Tests the not modified course being skipped.*/public function test_should_skip_not_modified_course_in_days(): void {global $DB;set_config('backup_auto_active', true, 'backup');// Skip if not modified in two days.set_config('backup_auto_skip_modif_days', 2, 'backup');set_config('backup_auto_weekdays', '1111111', 'backup');// Create this backup course.$backupcourse = new \stdClass;$backupcourse->courseid = $this->course->id;// This is the status we believe last run was OK.$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;$backupcourse->laststarttime = time() - 2 * DAYSECS;$backupcourse->lastendtime = time() - 1 * DAYSECS;$DB->insert_record('backup_courses', $backupcourse);$backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));$course = $DB->get_record('course', array('id' => $this->course->id));$course->timemodified = time() - 2 * DAYSECS - 1;$classobject = $this->backupcronautomatedhelper->return_this();$nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time());$method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup');$skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]);$this->assertTrue($skipped);$this->expectOutputRegex('/Skipping course id ' . $this->course->id . ': Not modified in the past 2 days/');}/*** Tests the backup not modified course being skipped.*/public function test_should_skip_not_modified_course_since_prev(): void {global $DB;set_config('backup_auto_active', true, 'backup');// Skip if not modified in two days.set_config('backup_auto_skip_modif_prev', 2, 'backup');set_config('backup_auto_weekdays', '1111111', 'backup');// Create this backup course.$backupcourse = new \stdClass;$backupcourse->courseid = $this->course->id;// This is the status we believe last run was OK.$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;$backupcourse->laststarttime = time() - 2 * DAYSECS;$backupcourse->lastendtime = time() - 1 * DAYSECS;$DB->insert_record('backup_courses', $backupcourse);$backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));$course = $DB->get_record('course', array('id' => $this->course->id));$course->timemodified = time() - 2 * DAYSECS - 1;$classobject = $this->backupcronautomatedhelper->return_this();$nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time());$method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup');$skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]);$this->assertTrue($skipped);$this->expectOutputRegex('/Skipping course id ' . $this->course->id . ': Not modified since previous backup/');}/*** Test the task completes when coureid is missing.*/public function test_task_complete_when_courseid_is_missing(): void {global $DB;$admin = get_admin();$classobject = $this->backupcronautomatedhelper->return_this();// Create this backup course.$backupcourse = new \stdClass;$backupcourse->courseid = $this->course->id;$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_NOTYETRUN;$DB->insert_record('backup_courses', $backupcourse);$backupcourse = $DB->get_record('backup_courses', ['courseid' => $this->course->id]);// Create a backup task.$method = new \ReflectionMethod('\backup_cron_automated_helper', 'push_course_backup_adhoc_task');$method->invokeArgs($classobject, [$backupcourse, $admin]);// Delete course for this test.delete_course($this->course->id, false);$task = \core\task\manager::get_next_adhoc_task(time());ob_start();$task->execute();$output = ob_get_clean();$this->assertStringContainsString('Invalid course id: ' . $this->course->id . ', task aborted.', $output);\core\task\manager::adhoc_task_complete($task);}/*** Test the task completes when backup course is missing.*/public function test_task_complete_when_backup_course_is_missing(): void {global $DB;$admin = get_admin();$classobject = $this->backupcronautomatedhelper->return_this();// Create this backup course.$backupcourse = new \stdClass;$backupcourse->courseid = $this->course->id;$backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_NOTYETRUN;$DB->insert_record('backup_courses', $backupcourse);$backupcourse = $DB->get_record('backup_courses', ['courseid' => $this->course->id]);// Create a backup task.$method = new \ReflectionMethod('\backup_cron_automated_helper', 'push_course_backup_adhoc_task');$method->invokeArgs($classobject, [$backupcourse, $admin]);// Delete backup course for this test.$DB->delete_records('backup_courses', ['courseid' => $this->course->id]);$task = \core\task\manager::get_next_adhoc_task(time());ob_start();$task->execute();$output = ob_get_clean();$this->assertStringContainsString('Automated backup for course: ' . $this->course->fullname . ' encounters an error.',$output);\core\task\manager::adhoc_task_complete($task);}}/*** New backup_cron_automated_helper class for testing.** This class extends the helper backup_cron_automated_helper class* in order to utilise abstract class for testing.** @package core* @copyright 2019 John Yao <johnyao@catalyst-au.net>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class test_backup_cron_automated_helper extends backup_cron_automated_helper {/*** Returning this for testing.*/public function return_this() {return $this;}}