Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 * Automated backup tests.
19
 *
20
 * @package    core_backup
21
 * @copyright  2019 John Yao <johnyao@catalyst-au.net>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_backup;
26
 
27
use backup_cron_automated_helper;
28
 
29
defined('MOODLE_INTERNAL') || die();
30
 
31
global $CFG;
32
require_once($CFG->dirroot . '/backup/util/helper/backup_cron_helper.class.php');
33
require_once($CFG->libdir . '/completionlib.php');
34
 
35
/**
36
 * Automated backup tests.
37
 *
38
 * @package    core_backup
39
 * @copyright  2019 John Yao <johnyao@catalyst-au.net>
40
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 */
42
class automated_backup_test extends \advanced_testcase {
43
    /**
44
     * @var \backup_cron_automated_helper
45
     */
46
    protected $backupcronautomatedhelper;
47
 
48
    /**
49
     * @var \stdClass $course
50
     */
51
    protected $course;
52
 
53
    protected function setUp(): void {
54
        global $DB, $CFG;
55
 
56
        $this->resetAfterTest(true);
57
        $this->setAdminUser();
58
        $CFG->enableavailability = true;
59
        $CFG->enablecompletion = true;
60
 
61
        // Getting a testable backup_cron_automated_helper class.
62
        $this->backupcronautomatedhelper = new test_backup_cron_automated_helper();
63
 
64
        $generator = $this->getDataGenerator();
65
        $this->course = $generator->create_course(
66
                array('format' => 'topics', 'numsections' => 3,
67
                        'enablecompletion' => COMPLETION_ENABLED),
68
                array('createsections' => true));
69
        $forum = $generator->create_module('forum', array(
70
                'course' => $this->course->id));
71
        $forum2 = $generator->create_module('forum', array(
72
                'course' => $this->course->id, 'completion' => COMPLETION_TRACKING_MANUAL));
73
 
74
        // We need a grade, easiest is to add an assignment.
75
        $assignrow = $generator->create_module('assign', array(
76
                'course' => $this->course->id));
77
        $assign = new \assign(\context_module::instance($assignrow->cmid), false, false);
78
        $item = $assign->get_grade_item();
79
 
80
        // Make a test grouping as well.
81
        $grouping = $generator->create_grouping(array('courseid' => $this->course->id,
82
                'name' => 'Grouping!'));
83
 
84
        $availability = '{"op":"|","show":false,"c":[' .
85
                '{"type":"completion","cm":' . $forum2->cmid .',"e":1},' .
86
                '{"type":"grade","id":' . $item->id . ',"min":4,"max":94},' .
87
                '{"type":"grouping","id":' . $grouping->id . '}' .
88
                ']}';
89
        $DB->set_field('course_modules', 'availability', $availability, array(
90
                'id' => $forum->cmid));
91
        $DB->set_field('course_sections', 'availability', $availability, array(
92
                'course' => $this->course->id, 'section' => 1));
93
    }
94
 
95
    /**
96
     * Tests the automated backup run when the there is course backup should be skipped.
97
     */
11 efrain 98
    public function test_automated_backup_skipped_run(): void {
1 efrain 99
        global $DB;
100
 
101
        // Enable automated back up.
102
        set_config('backup_auto_active', true, 'backup');
103
        set_config('backup_auto_weekdays', '1111111', 'backup');
104
 
105
        // Start backup process.
106
        $admin = get_admin();
107
 
108
        // Backup entry should not exist.
109
        $backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));
110
        $this->assertFalse($backupcourse);
111
        $this->assertInstanceOf(
112
            backup_cron_automated_helper::class,
113
            $this->backupcronautomatedhelper->return_this()
114
        );
115
 
116
        $classobject = $this->backupcronautomatedhelper->return_this();
117
 
118
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'get_courses');
119
        $courses = $method->invoke($classobject);
120
 
121
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'check_and_push_automated_backups');
122
        $emailpending = $method->invokeArgs($classobject, [$courses, $admin]);
123
 
124
        $this->expectOutputRegex('/Skipping course id ' . $this->course->id . ': Not scheduled for backup until/');
125
        $this->assertFalse($emailpending);
126
 
127
        $backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));
128
        $this->assertNotNull($backupcourse->laststatus);
129
    }
130
 
131
    /**
132
     * Tests the automated backup run when the there is course backup can be pushed to adhoc task.
133
     */
11 efrain 134
    public function test_automated_backup_push_run(): void {
1 efrain 135
        global $DB;
136
 
137
        // Enable automated back up.
138
        set_config('backup_auto_active', true, 'backup');
139
        set_config('backup_auto_weekdays', '1111111', 'backup');
140
 
141
        $admin = get_admin();
142
 
143
        $classobject = $this->backupcronautomatedhelper->return_this();
144
 
145
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'get_courses');
146
        $courses = $method->invoke($classobject);
147
 
148
        // Create this backup course.
149
        $backupcourse = new \stdClass;
150
        $backupcourse->courseid = $this->course->id;
151
        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_NOTYETRUN;
152
        $DB->insert_record('backup_courses', $backupcourse);
153
        $backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));
154
 
155
        // We now manually trigger a backup pushed to adhoc task.
156
        // Make sure is in the past, which means should run now.
157
        $backupcourse->nextstarttime = time() - 10;
158
        $DB->update_record('backup_courses', $backupcourse);
159
 
160
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'check_and_push_automated_backups');
161
        $emailpending = $method->invokeArgs($classobject, [$courses, $admin]);
162
        $this->assertTrue($emailpending);
163
 
164
        $this->expectOutputRegex('/Putting backup of course id ' . $this->course->id. ' in adhoc task queue/');
165
 
166
        $backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));
167
        // Now this backup course status should be queued.
168
        $this->assertEquals(backup_cron_automated_helper::BACKUP_STATUS_QUEUED, $backupcourse->laststatus);
169
    }
170
 
171
    /**
172
     * Tests the automated backup inactive run.
173
     */
11 efrain 174
    public function test_inactive_run(): void {
1 efrain 175
        backup_cron_automated_helper::run_automated_backup();
176
        $this->expectOutputString("Checking automated backup status...INACTIVE\n");
177
    }
178
 
179
    /**
180
     * Tests the invisible course being skipped.
181
     */
11 efrain 182
    public function test_should_skip_invisible_course(): void {
1 efrain 183
        global $DB;
184
 
185
        set_config('backup_auto_active', true, 'backup');
186
        set_config('backup_auto_skip_hidden', true, 'backup');
187
        set_config('backup_auto_weekdays', '1111111', 'backup');
188
        // Create this backup course.
189
        $backupcourse = new \stdClass;
190
        $backupcourse->courseid = $this->course->id;
191
        // This is the status we believe last run was OK.
192
        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;
193
        $DB->insert_record('backup_courses', $backupcourse);
194
        $backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));
195
 
196
        $this->assertTrue(course_change_visibility($this->course->id, false));
197
        $course = $DB->get_record('course', array('id' => $this->course->id));
198
        $this->assertEquals('0', $course->visible);
199
        $classobject = $this->backupcronautomatedhelper->return_this();
200
        $nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time());
201
 
202
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup');
203
        $skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]);
204
 
205
        $this->assertTrue($skipped);
206
        $this->expectOutputRegex('/Skipping course id ' . $this->course->id. ': Not visible/');
207
    }
208
 
209
    /**
210
     * Tests the not modified course being skipped.
211
     */
11 efrain 212
    public function test_should_skip_not_modified_course_in_days(): void {
1 efrain 213
        global $DB;
214
 
215
        set_config('backup_auto_active', true, 'backup');
216
        // Skip if not modified in two days.
217
        set_config('backup_auto_skip_modif_days', 2, 'backup');
218
        set_config('backup_auto_weekdays', '1111111', 'backup');
219
 
220
        // Create this backup course.
221
        $backupcourse = new \stdClass;
222
        $backupcourse->courseid = $this->course->id;
223
        // This is the status we believe last run was OK.
224
        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;
225
        $backupcourse->laststarttime = time() - 2 * DAYSECS;
226
        $backupcourse->lastendtime = time() - 1 * DAYSECS;
227
        $DB->insert_record('backup_courses', $backupcourse);
228
        $backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));
229
        $course = $DB->get_record('course', array('id' => $this->course->id));
230
 
231
        $course->timemodified = time() - 2 * DAYSECS - 1;
232
 
233
        $classobject = $this->backupcronautomatedhelper->return_this();
234
        $nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time());
235
 
236
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup');
237
        $skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]);
238
 
239
        $this->assertTrue($skipped);
240
        $this->expectOutputRegex('/Skipping course id ' . $this->course->id . ': Not modified in the past 2 days/');
241
    }
242
 
243
    /**
244
     * Tests the backup not modified course being skipped.
245
     */
11 efrain 246
    public function test_should_skip_not_modified_course_since_prev(): void {
1 efrain 247
        global $DB;
248
 
249
        set_config('backup_auto_active', true, 'backup');
250
        // Skip if not modified in two days.
251
        set_config('backup_auto_skip_modif_prev', 2, 'backup');
252
        set_config('backup_auto_weekdays', '1111111', 'backup');
253
 
254
        // Create this backup course.
255
        $backupcourse = new \stdClass;
256
        $backupcourse->courseid = $this->course->id;
257
        // This is the status we believe last run was OK.
258
        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_SKIPPED;
259
        $backupcourse->laststarttime = time() - 2 * DAYSECS;
260
        $backupcourse->lastendtime = time() - 1 * DAYSECS;
261
        $DB->insert_record('backup_courses', $backupcourse);
262
        $backupcourse = $DB->get_record('backup_courses', array('courseid' => $this->course->id));
263
        $course = $DB->get_record('course', array('id' => $this->course->id));
264
 
265
        $course->timemodified = time() - 2 * DAYSECS - 1;
266
 
267
        $classobject = $this->backupcronautomatedhelper->return_this();
268
        $nextstarttime = backup_cron_automated_helper::calculate_next_automated_backup(null, time());
269
 
270
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'should_skip_course_backup');
271
        $skipped = $method->invokeArgs($classobject, [$backupcourse, $course, $nextstarttime]);
272
 
273
        $this->assertTrue($skipped);
274
        $this->expectOutputRegex('/Skipping course id ' . $this->course->id . ': Not modified since previous backup/');
275
    }
276
 
277
    /**
278
     * Test the task completes when coureid is missing.
279
     */
11 efrain 280
    public function test_task_complete_when_courseid_is_missing(): void {
1 efrain 281
        global $DB;
282
        $admin = get_admin();
283
        $classobject = $this->backupcronautomatedhelper->return_this();
284
 
285
        // Create this backup course.
286
        $backupcourse = new \stdClass;
287
        $backupcourse->courseid = $this->course->id;
288
        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_NOTYETRUN;
289
        $DB->insert_record('backup_courses', $backupcourse);
290
        $backupcourse = $DB->get_record('backup_courses', ['courseid' => $this->course->id]);
291
 
292
        // Create a backup task.
293
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'push_course_backup_adhoc_task');
294
        $method->invokeArgs($classobject, [$backupcourse, $admin]);
295
 
296
        // Delete course for this test.
297
        delete_course($this->course->id, false);
298
 
299
        $task = \core\task\manager::get_next_adhoc_task(time());
300
 
301
        ob_start();
302
        $task->execute();
303
        $output = ob_get_clean();
304
 
305
        $this->assertStringContainsString('Invalid course id: ' . $this->course->id . ', task aborted.', $output);
306
        \core\task\manager::adhoc_task_complete($task);
307
    }
308
 
309
    /**
310
     * Test the task completes when backup course is missing.
311
     */
11 efrain 312
    public function test_task_complete_when_backup_course_is_missing(): void {
1 efrain 313
        global $DB;
314
        $admin = get_admin();
315
        $classobject = $this->backupcronautomatedhelper->return_this();
316
 
317
        // Create this backup course.
318
        $backupcourse = new \stdClass;
319
        $backupcourse->courseid = $this->course->id;
320
        $backupcourse->laststatus = backup_cron_automated_helper::BACKUP_STATUS_NOTYETRUN;
321
        $DB->insert_record('backup_courses', $backupcourse);
322
        $backupcourse = $DB->get_record('backup_courses', ['courseid' => $this->course->id]);
323
 
324
        // Create a backup task.
325
        $method = new \ReflectionMethod('\backup_cron_automated_helper', 'push_course_backup_adhoc_task');
326
        $method->invokeArgs($classobject, [$backupcourse, $admin]);
327
 
328
        // Delete backup course for this test.
329
        $DB->delete_records('backup_courses', ['courseid' => $this->course->id]);
330
 
331
        $task = \core\task\manager::get_next_adhoc_task(time());
332
 
333
        ob_start();
334
        $task->execute();
335
        $output = ob_get_clean();
336
 
337
        $this->assertStringContainsString('Automated backup for course: ' . $this->course->fullname . ' encounters an error.',
338
            $output);
339
        \core\task\manager::adhoc_task_complete($task);
340
    }
341
}
342
 
343
/**
344
 * New backup_cron_automated_helper class for testing.
345
 *
346
 * This class extends the helper backup_cron_automated_helper class
347
 * in order to utilise abstract class for testing.
348
 *
349
 * @package    core
350
 * @copyright  2019 John Yao <johnyao@catalyst-au.net>
351
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
352
 */
353
class test_backup_cron_automated_helper extends backup_cron_automated_helper {
354
    /**
355
     * Returning this for testing.
356
     */
357
    public function return_this() {
358
        return $this;
359
    }
360
}