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
namespace core\task;
18
 
1441 ariadna 19
use stdClass;
20
 
1 efrain 21
/**
22
 * Unit tests for the file_temp_cleanup task.
23
 *
24
 * @package   core
25
 * @category  test
26
 * @copyright 2013 Tim Gusak <tim.gusak@remote-learner.net>
27
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28
 * @covers    \core\task\file_temp_cleanup_task
29
 */
1441 ariadna 30
final class file_temp_cleanup_task_test extends \basic_testcase {
1 efrain 31
    /**
32
     * Data provider for cron_delete_from_temp.
33
     *
34
     * @return array Provider data
35
     */
1441 ariadna 36
    public static function cron_delete_from_temp_provider(): array {
1 efrain 37
        global $CFG;
38
 
39
        $tmpdir = realpath($CFG->tempdir);
40
        // This is a relative time.
41
        $time = 0;
42
 
43
        // Relative time stamps. Did you know data providers get executed during phpunit init?
44
        $lastweekstime = -($CFG->tempdatafoldercleanup * 3600); // This must match file_temp_cleanup_task.
45
        $beforelastweekstime = $lastweekstime - 3600 - 1; // At least 1h and 1s diff (make it DST immune).
46
        $afterlastweekstime = $lastweekstime + 3600 + 1; // At least 1h and 1s diff (make it DST immune).
47
 
48
        $nodes = array();
49
        // Really old directory to remove.
1441 ariadna 50
        $nodes[] = self::generate_test_path('/dir1/dir1_1/dir1_1_1/dir1_1_1_1/', true, $lastweekstime * 52, false);
1 efrain 51
 
52
        // New Directory to keep.
1441 ariadna 53
        $nodes[] = self::generate_test_path('/dir1/dir1_2/', true, $time, true);
1 efrain 54
 
55
        // Directory a little less than 1 week old, keep.
1441 ariadna 56
        $nodes[] = self::generate_test_path('/dir2/', true, $afterlastweekstime, true);
1 efrain 57
 
58
        // Directory older than 1 week old, remove.
1441 ariadna 59
        $nodes[] = self::generate_test_path('/dir3/', true, $beforelastweekstime, false);
1 efrain 60
 
61
        // File older than 1 week old, remove.
1441 ariadna 62
        $nodes[] = self::generate_test_path('/dir1/dir1_1/dir1_1_1/file1_1_1_1', false, $beforelastweekstime, false);
1 efrain 63
 
64
        // New File to keep.
1441 ariadna 65
        $nodes[] = self::generate_test_path('/dir1/dir1_1/dir1_1_1/file1_1_1_2', false, $time, true);
1 efrain 66
 
67
        // File older than 1 week old, remove.
1441 ariadna 68
        $nodes[] = self::generate_test_path('/dir1/dir1_2/file1_1_2_1', false, $beforelastweekstime, false);
1 efrain 69
 
70
        // New file to keep.
1441 ariadna 71
        $nodes[] = self::generate_test_path('/dir1/dir1_2/file1_1_2_2', false, $time, true);
1 efrain 72
 
73
        // New file to keep.
1441 ariadna 74
        $nodes[] = self::generate_test_path('/file1', false, $time, true);
1 efrain 75
 
76
        // File older than 1 week, keep.
1441 ariadna 77
        $nodes[] = self::generate_test_path('/file2', false, $beforelastweekstime, false);
1 efrain 78
 
79
        // Directory older than 1 week to keep.
80
        // Note: Since this directory contains a directory that contains a file that is also older than a week
81
        // the directory won't be deleted since it's mtime will be updated when the file is deleted.
82
 
1441 ariadna 83
        $nodes[] = self::generate_test_path('/dir4/dir4_1', true, $beforelastweekstime, true);
1 efrain 84
 
1441 ariadna 85
        $nodes[] = self::generate_test_path('/dir4/dir4_1/dir4_1_1/', true, $beforelastweekstime, true);
1 efrain 86
 
87
        // File older than 1 week to remove.
1441 ariadna 88
        $nodes[] = self::generate_test_path('/dir4/dir4_1/dir4_1_1/file4_1_1_1', false, $beforelastweekstime, false);
1 efrain 89
 
90
        $expectednodes = array();
91
        foreach ($nodes as $node) {
92
            if ($node->keep) {
93
                $path = $tmpdir;
94
                $pelements = preg_split('/\//', $node->path);
95
                foreach ($pelements as $pelement) {
96
                    if ($pelement === '') {
97
                        continue;
98
                    }
99
                    $path .= DIRECTORY_SEPARATOR . $pelement;
100
                    if (!in_array($path, $expectednodes)) {
101
                        $expectednodes[] = $path;
102
                    }
103
                }
104
            }
105
        }
106
        sort($expectednodes);
107
 
1441 ariadna 108
        $data = [
109
            [$nodes, $expectednodes],
110
            [[], []],
111
        ];
1 efrain 112
 
113
        return $data;
114
    }
115
 
116
    /**
117
     * Function to populate node array.
118
     *
119
     * @param string $path Path of directory or file
120
     * @param bool $isdir Is the node a directory
121
     * @param int $time modified time of the node in epoch
122
     * @param bool $keep Should the node exist after the delete function has run
123
     */
1441 ariadna 124
    private static function generate_test_path($path, $isdir = false, $time = 0, $keep = false): stdClass {
125
        return (object) [
126
            'path' => $path,
127
            'isdir' => $isdir,
128
            'time' => $time,
129
            'keep' => $keep,
130
        ];
1 efrain 131
    }
132
    /**
133
     * Test removing files and directories from tempdir.
134
     *
135
     * @dataProvider cron_delete_from_temp_provider
136
     * @param array $nodes List of files and directories
137
     * @param array $expected The expected results
138
     */
11 efrain 139
    public function test_cron_delete_from_temp($nodes, $expected): void {
1 efrain 140
        global $CFG;
141
 
142
        $tmpdir = realpath($CFG->tempdir);
143
 
144
        foreach ($nodes as $data) {
145
            if ($data->isdir) {
146
                mkdir($tmpdir.$data->path, $CFG->directorypermissions, true);
147
            }
148
        }
149
        // We need to iterate through again since adding a file to a directory will
150
        // update the modified time of the directory.
151
        foreach ($nodes as $data) {
152
            touch($tmpdir.$data->path, time() + $data->time);
153
        }
154
 
155
        $task = new \core\task\file_temp_cleanup_task();
156
        $task->execute();
157
 
158
        $dir = new \RecursiveDirectoryIterator($tmpdir);
159
        $iter = new \RecursiveIteratorIterator($dir, \RecursiveIteratorIterator::CHILD_FIRST);
160
 
161
        $actual = array();
162
        for ($iter->rewind(); $iter->valid(); $iter->next()) {
163
            $isvalid = true;
164
            $isvalid = $isvalid && !$iter->isDot();
165
            // Remove the default $CFG->tempdir/backup directory and $CFG->tempdir/.htaccess file from this comparison.
166
            $isvalid = $isvalid && !($iter->isDir() && ($iter->getRealpath() === $tmpdir . DIRECTORY_SEPARATOR . 'backup'));
167
            $isvalid = $isvalid && !($iter->isFile() && ($iter->getRealpath() === $tmpdir . DIRECTORY_SEPARATOR . '.htaccess'));
168
            if ($isvalid) {
169
                $actual[] = $iter->getRealPath();
170
            }
171
        }
172
 
173
        // Sort results to guarantee actual order.
174
        sort($actual);
175
 
176
        $this->assertEquals($expected, $actual);
177
    }
178
}