[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/tests/ -> scheduled_task_test.php (source)

   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   * This file contains the unittests for scheduled tasks.
  19   *
  20   * @package   core
  21   * @category  phpunit
  22   * @copyright 2013 Damyon Wiese
  23   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  require_once (__DIR__ . '/fixtures/task_fixtures.php');
  28  
  29  /**
  30   * Test class for scheduled task.
  31   *
  32   * @package core
  33   * @category task
  34   * @copyright 2013 Damyon Wiese
  35   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class core_scheduled_task_testcase extends advanced_testcase {
  38  
  39      /**
  40       * Test the cron scheduling method
  41       */
  42      public function test_eval_cron_field() {
  43          $testclass = new \core\task\scheduled_test_task();
  44  
  45          $this->assertEquals(20, count($testclass->eval_cron_field('*/3', 0, 59)));
  46          $this->assertEquals(31, count($testclass->eval_cron_field('1,*/2', 0, 59)));
  47          $this->assertEquals(15, count($testclass->eval_cron_field('1-10,5-15', 0, 59)));
  48          $this->assertEquals(13, count($testclass->eval_cron_field('1-10,5-15/2', 0, 59)));
  49          $this->assertEquals(3, count($testclass->eval_cron_field('1,2,3,1,2,3', 0, 59)));
  50          $this->assertEquals(1, count($testclass->eval_cron_field('-1,10,80', 0, 59)));
  51      }
  52  
  53      public function test_get_next_scheduled_time() {
  54          // Test job run at 1 am.
  55          $testclass = new \core\task\scheduled_test_task();
  56  
  57          // All fields default to '*'.
  58          $testclass->set_hour('1');
  59          $testclass->set_minute('0');
  60          // Next valid time should be 1am of the next day.
  61          $nexttime = $testclass->get_next_scheduled_time();
  62  
  63          $oneam = mktime(1, 0, 0);
  64          // Make it 1 am tomorrow if the time is after 1am.
  65          if ($oneam < time()) {
  66              $oneam += 86400;
  67          }
  68  
  69          $this->assertEquals($oneam, $nexttime, 'Next scheduled time is 1am.');
  70  
  71          // Disabled flag does not affect next time.
  72          $testclass->set_disabled(true);
  73          $nexttime = $testclass->get_next_scheduled_time();
  74          $this->assertEquals($oneam, $nexttime, 'Next scheduled time is 1am.');
  75  
  76          // Now test for job run every 10 minutes.
  77          $testclass = new \core\task\scheduled_test_task();
  78  
  79          // All fields default to '*'.
  80          $testclass->set_minute('*/10');
  81          // Next valid time should be next 10 minute boundary.
  82          $nexttime = $testclass->get_next_scheduled_time();
  83  
  84          $minutes = ((intval(date('i') / 10))+1) * 10;
  85          $nexttenminutes = mktime(date('H'), $minutes, 0);
  86  
  87          $this->assertEquals($nexttenminutes, $nexttime, 'Next scheduled time is in 10 minutes.');
  88  
  89          // Disabled flag does not affect next time.
  90          $testclass->set_disabled(true);
  91          $nexttime = $testclass->get_next_scheduled_time();
  92          $this->assertEquals($nexttenminutes, $nexttime, 'Next scheduled time is in 10 minutes.');
  93  
  94          // Test hourly job executed on Sundays only.
  95          $testclass = new \core\task\scheduled_test_task();
  96          $testclass->set_minute('0');
  97          $testclass->set_day_of_week('7');
  98  
  99          $nexttime = $testclass->get_next_scheduled_time();
 100  
 101          $this->assertEquals(7, date('N', $nexttime));
 102          $this->assertEquals(0, date('i', $nexttime));
 103  
 104          // Test monthly job
 105          $testclass = new \core\task\scheduled_test_task();
 106          $testclass->set_minute('32');
 107          $testclass->set_hour('0');
 108          $testclass->set_day('1');
 109  
 110          $nexttime = $testclass->get_next_scheduled_time();
 111  
 112          $this->assertEquals(32, date('i', $nexttime));
 113          $this->assertEquals(0, date('G', $nexttime));
 114          $this->assertEquals(1, date('j', $nexttime));
 115      }
 116  
 117      public function test_timezones() {
 118          global $CFG, $USER;
 119  
 120          // The timezones used in this test are chosen because they do not use DST - that would break the test.
 121  
 122          $currenttimezonephp = date_default_timezone_get();
 123          $currenttimezonecfg = null;
 124          if (!empty($CFG->timezone)) {
 125              $currenttimezonecfg = $CFG->timezone;
 126          }
 127          $userstimezone = null;
 128          if (!empty($USER->timezone)) {
 129              $userstimezone = $USER->timezone;
 130          }
 131  
 132          // We are testing a difference between $CFG->timezone and the php.ini timezone.
 133          // GMT+8.
 134          date_default_timezone_set('Australia/Perth');
 135          // GMT-04:30.
 136          $CFG->timezone = 'America/Caracas';
 137  
 138          $testclass = new \core\task\scheduled_test_task();
 139  
 140          // Scheduled tasks should always use servertime - so this is 03:30 GMT.
 141          $testclass->set_hour('1');
 142          $testclass->set_minute('0');
 143  
 144          // Next valid time should be 1am of the next day.
 145          $nexttime = $testclass->get_next_scheduled_time();
 146  
 147          // GMT+05:45.
 148          $USER->timezone = 'Asia/Kathmandu';
 149          $userdate = userdate($nexttime);
 150  
 151          // Should be displayed in user timezone.
 152          // I used http://www.timeanddate.com/worldclock/fixedtime.html?msg=Moodle+Test&iso=20140314T01&p1=58
 153          // to verify this time.
 154          $this->assertContains('11:15 AM', core_text::strtoupper($userdate));
 155  
 156          $CFG->timezone = $currenttimezonecfg;
 157          date_default_timezone_set($currenttimezonephp);
 158      }
 159  
 160      public function test_reset_scheduled_tasks_for_component() {
 161          global $DB;
 162  
 163          $this->resetAfterTest(true);
 164          // Remember the defaults.
 165          $defaulttasks = \core\task\manager::load_scheduled_tasks_for_component('moodle');
 166          $initcount = count($defaulttasks);
 167          // Customise a task.
 168          $firsttask = reset($defaulttasks);
 169          $firsttask->set_minute('1');
 170          $firsttask->set_hour('2');
 171          $firsttask->set_month('3');
 172          $firsttask->set_day_of_week('4');
 173          $firsttask->set_day('5');
 174          $firsttask->set_customised('1');
 175          \core\task\manager::configure_scheduled_task($firsttask);
 176          $firsttaskrecord = \core\task\manager::record_from_scheduled_task($firsttask);
 177          // We reset this field, because we do not want to compare it.
 178          $firsttaskrecord->nextruntime = '0';
 179  
 180          // Now call reset on all the tasks.
 181          \core\task\manager::reset_scheduled_tasks_for_component('moodle');
 182  
 183          // Load the tasks again.
 184          $defaulttasks = \core\task\manager::load_scheduled_tasks_for_component('moodle');
 185          $finalcount = count($defaulttasks);
 186          // Compare the first task.
 187          $newfirsttask = reset($defaulttasks);
 188          $newfirsttaskrecord = \core\task\manager::record_from_scheduled_task($newfirsttask);
 189          // We reset this field, because we do not want to compare it.
 190          $newfirsttaskrecord->nextruntime = '0';
 191  
 192          // Assert a customised task was not altered by reset.
 193          $this->assertEquals($firsttaskrecord, $newfirsttaskrecord);
 194  
 195          // Assert we have the same number of tasks.
 196          $this->assertEquals($initcount, $finalcount);
 197      }
 198  
 199      public function test_get_next_scheduled_task() {
 200          global $DB;
 201  
 202          $this->resetAfterTest(true);
 203          // Delete all existing scheduled tasks.
 204          $DB->delete_records('task_scheduled');
 205          // Add a scheduled task.
 206  
 207          // A task that runs once per hour.
 208          $record = new stdClass();
 209          $record->blocking = true;
 210          $record->minute = '0';
 211          $record->hour = '0';
 212          $record->dayofweek = '*';
 213          $record->day = '*';
 214          $record->month = '*';
 215          $record->component = 'test_scheduled_task';
 216          $record->classname = '\core\task\scheduled_test_task';
 217  
 218          $DB->insert_record('task_scheduled', $record);
 219          // And another one to test failures.
 220          $record->classname = '\core\task\scheduled_test2_task';
 221          $DB->insert_record('task_scheduled', $record);
 222          // And disabled test.
 223          $record->classname = '\core\task\scheduled_test3_task';
 224          $record->disabled = 1;
 225          $DB->insert_record('task_scheduled', $record);
 226  
 227          $now = time();
 228  
 229          // Should get handed the first task.
 230          $task = \core\task\manager::get_next_scheduled_task($now);
 231          $this->assertInstanceOf('\core\task\scheduled_test_task', $task);
 232          $task->execute();
 233  
 234          \core\task\manager::scheduled_task_complete($task);
 235          // Should get handed the second task.
 236          $task = \core\task\manager::get_next_scheduled_task($now);
 237          $this->assertInstanceOf('\core\task\scheduled_test2_task', $task);
 238          $task->execute();
 239  
 240          \core\task\manager::scheduled_task_failed($task);
 241          // Should not get any task.
 242          $task = \core\task\manager::get_next_scheduled_task($now);
 243          $this->assertNull($task);
 244  
 245          // Should get the second task (retry after delay).
 246          $task = \core\task\manager::get_next_scheduled_task($now + 120);
 247          $this->assertInstanceOf('\core\task\scheduled_test2_task', $task);
 248          $task->execute();
 249  
 250          \core\task\manager::scheduled_task_complete($task);
 251  
 252          // Should not get any task.
 253          $task = \core\task\manager::get_next_scheduled_task($now);
 254          $this->assertNull($task);
 255      }
 256  
 257      public function test_get_broken_scheduled_task() {
 258          global $DB;
 259  
 260          $this->resetAfterTest(true);
 261          // Delete all existing scheduled tasks.
 262          $DB->delete_records('task_scheduled');
 263          // Add a scheduled task.
 264  
 265          // A broken task that runs all the time.
 266          $record = new stdClass();
 267          $record->blocking = true;
 268          $record->minute = '*';
 269          $record->hour = '*';
 270          $record->dayofweek = '*';
 271          $record->day = '*';
 272          $record->month = '*';
 273          $record->component = 'test_scheduled_task';
 274          $record->classname = '\core\task\scheduled_test_task_broken';
 275  
 276          $DB->insert_record('task_scheduled', $record);
 277  
 278          $now = time();
 279          // Should not get any task.
 280          $task = \core\task\manager::get_next_scheduled_task($now);
 281          $this->assertDebuggingCalled();
 282          $this->assertNull($task);
 283      }
 284  
 285      /**
 286       * Tests the use of 'R' syntax in time fields of tasks to get
 287       * tasks be configured with a non-uniform time.
 288       */
 289      public function test_random_time_specification() {
 290  
 291          // Testing non-deterministic things in a unit test is not really
 292          // wise, so we just test the values have changed within allowed bounds.
 293          $testclass = new \core\task\scheduled_test_task();
 294  
 295          // The test task defaults to '*'.
 296          $this->assertInternalType('string', $testclass->get_minute());
 297          $this->assertInternalType('string', $testclass->get_hour());
 298  
 299          // Set a random value.
 300          $testclass->set_minute('R');
 301          $testclass->set_hour('R');
 302  
 303          // Verify the minute has changed within allowed bounds.
 304          $minute = $testclass->get_minute();
 305          $this->assertInternalType('int', $minute);
 306          $this->assertGreaterThanOrEqual(0, $minute);
 307          $this->assertLessThanOrEqual(59, $minute);
 308  
 309          // Verify the hour has changed within allowed bounds.
 310          $hour = $testclass->get_hour();
 311          $this->assertInternalType('int', $hour);
 312          $this->assertGreaterThanOrEqual(0, $hour);
 313          $this->assertLessThanOrEqual(23, $hour);
 314      }
 315  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1