Proyectos de Subversion Moodle

Rev

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