Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

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