MDL-45654 cron: fixed dataprovider timestamp issue
[moodle.git] / lib / tests / cronlib_test.php
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/>.
17 /**
18  * Unit tests for the cron.
19  *
20  * @package   core
21  * @category  test
22  * @copyright 2013 Tim Gusak <tim.gusak@remote-learner.net>
23  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
29 require_once($CFG->libdir.'/cronlib.php');
31 class cronlib_testcase extends basic_testcase {
33     /**
34      * Data provider for cron_delete_from_temp.
35      *
36      * @return array Provider data
37      */
38     public function cron_delete_from_temp_provider() {
39         global $CFG;
41         $tmpdir = realpath($CFG->tempdir);
42         $time = time();
44         // Relative time stamps. Did you know data providers get executed during phpunit init?
45         $lastweekstime = -(7 * 24 * 60 * 60);
46         $beforelastweekstime = $lastweekstime - 60;
47         $afterlastweekstime = $lastweekstime + 60;
49         $nodes = array();
50         // Really old directory to remove.
51         $nodes[] = $this->generate_test_path('/dir1/dir1_1/dir1_1_1/dir1_1_1_1/', true, $lastweekstime * 52, false);
53         // New Directory to keep.
54         $nodes[] = $this->generate_test_path('/dir1/dir1_2/', true, $time, true);
56         // Directory exactly 1 week old, keep.
57         $nodes[] = $this->generate_test_path('/dir2/', true, $lastweekstime, true);
59         // Directory older than 1 week old, remove.
60         $nodes[] = $this->generate_test_path('/dir3/', true, $beforelastweekstime, false);
62         // File older than 1 week old, remove.
63         $nodes[] = $this->generate_test_path('/dir1/dir1_1/dir1_1_1/file1_1_1_1', false, $beforelastweekstime, false);
65         // New File to keep.
66         $nodes[] = $this->generate_test_path('/dir1/dir1_1/dir1_1_1/file1_1_1_2', false, $time, true);
68         // File older than 1 week old, remove.
69         $nodes[] = $this->generate_test_path('/dir1/dir1_2/file1_1_2_1', false, $beforelastweekstime, false);
71         // New file to keep.
72         $nodes[] = $this->generate_test_path('/dir1/dir1_2/file1_1_2_2', false, $time, true);
74         // New file to keep.
75         $nodes[] = $this->generate_test_path('/file1', false, $time, true);
77         // File older than 1 week, keep.
78         $nodes[] = $this->generate_test_path('/file2', false, $beforelastweekstime, false);
80         // Directory older than 1 week to keep.
81         // Note: Since this directory contains a directory that contains a file that is also older than a week
82         // the directory won't be deleted since it's mtime will be updated when the file is deleted.
84         $nodes[] = $this->generate_test_path('/dir4/dir4_1', true, $beforelastweekstime, true);
86         $nodes[] = $this->generate_test_path('/dir4/dir4_1/dir4_1_1/', true, $beforelastweekstime, true);
88         // File older than 1 week to remove.
89         $nodes[] = $this->generate_test_path('/dir4/dir4_1/dir4_1_1/file4_1_1_1', false, $beforelastweekstime, false);
91         $expectednodes = array();
92         foreach ($nodes as $node) {
93             if ($node->keep) {
94                 $path = $tmpdir;
95                 $pelements = preg_split('/\//', $node->path);
96                 foreach ($pelements as $pelement) {
97                     if ($pelement === '') {
98                         continue;
99                     }
100                     $path .= DIRECTORY_SEPARATOR . $pelement;
101                     if (!in_array($path, $expectednodes)) {
102                         $expectednodes[] = $path;
103                     }
104                 }
105             }
106         }
107         sort($expectednodes);
109         $data = array(
110                 array(
111                     $nodes,
112                     $expectednodes
113                 ),
114                 array(
115                     array(),
116                     array()
117                 )
118         );
120         return $data;
121     }
123     /**
124      * Function to populate node array.
125      *
126      * @param string $path Path of directory or file
127      * @param bool $isdir Is the node a directory
128      * @param int $time modified time of the node in epoch
129      * @param bool $keep Should the node exist after the delete function has run
130      */
131     private function generate_test_path($path, $isdir = false, $time = 0, $keep = false) {
132         $node = new stdClass();
133         $node->path = $path;
134         $node->isdir = $isdir;
135         $node->time = $time;
136         $node->keep = $keep;
137         return $node;
138     }
139     /**
140      * Test removing files and directories from tempdir.
141      *
142      * @dataProvider cron_delete_from_temp_provider
143      * @param array $nodes List of files and directories
144      * @param array $expected The expected results
145      */
146     public function test_cron_delete_from_temp($nodes, $expected) {
147         global $CFG;
149         $tmpdir = $CFG->tempdir;
151         foreach ($nodes as $data) {
152             if ($data->isdir) {
153                 mkdir($tmpdir.$data->path, $CFG->directorypermissions, true);
154             }
155         }
156         // We need to iterate through again since adding a file to a directory will
157         // update the modified time of the directory.
158         foreach ($nodes as $data) {
159             touch($tmpdir.$data->path, time() + $data->time);
160         }
162         $task = new \core\task\file_temp_cleanup_task();
163         $task->execute();
165         $dir = new RecursiveDirectoryIterator($tmpdir);
166         $iter = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
168         $actual = array();
169         for ($iter->rewind(); $iter->valid(); $iter->next()) {
170             if (!$iter->isDot()) {
171                 $actual[] = $iter->getRealPath();
172             }
173         }
175         // Sort results to guarantee actual order.
176         sort($actual);
178         $this->assertEquals($expected, $actual);
179     }