TYPO3 CMS  TYPO3_8-7
CronCommandTest.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
18 
22 class CronCommandTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
23 {
27  const TIMESTAMP = 1262304000;
28 
32  protected $timezoneBackup = '';
33 
40  protected function setUp()
41  {
42  $this->timezoneBackup = date_default_timezone_get();
43  date_default_timezone_set('UTC');
44  }
45 
46  protected function tearDown()
47  {
48  date_default_timezone_set($this->timezoneBackup);
49  parent::tearDown();
50  }
51 
56  {
57  $instance = new CronCommand('2-3 * * * *');
58  $this->assertSame(['2,3', '*', '*', '*', '*'], $instance->getCronCommandSections());
59  }
60 
65  {
66  $this->expectException(\InvalidArgumentException::class);
67  $this->expectExceptionCode(1291470170);
68  new CronCommand('61 * * * *');
69  }
70 
75  {
76  $instance = new CronCommand('* * * * *');
77  $currentTime = time();
78  $expectedTime = $currentTime - ($currentTime % 60) + 60;
79  $this->assertSame($expectedTime, $instance->getTimestamp());
80  }
81 
86  {
87  $instance = new CronCommand('* * * * *', self::TIMESTAMP);
88  $this->assertSame(self::TIMESTAMP + 60, $instance->getTimestamp());
89  }
90 
95  {
96  $instance = new CronCommand('* * * * *', self::TIMESTAMP + 1);
97  $this->assertSame(self::TIMESTAMP + 60, $instance->getTimestamp());
98  }
99 
103  public static function expectedTimestampDataProvider()
104  {
105  return [
106  'every minute' => [
107  '* * * * *',
108  self::TIMESTAMP,
109  self::TIMESTAMP + 60,
110  self::TIMESTAMP + 120
111  ],
112  'once an hour at 1' => [
113  '1 * * * *',
114  self::TIMESTAMP,
115  self::TIMESTAMP + 60,
116  self::TIMESTAMP + 60 + 60 * 60
117  ],
118  'once an hour at 0' => [
119  '0 * * * *',
120  self::TIMESTAMP,
121  self::TIMESTAMP + 60 * 60,
122  self::TIMESTAMP + 60 * 60 + 60 * 60
123  ],
124  'once a day at 1:00' => [
125  '0 1 * * *',
126  self::TIMESTAMP,
127  self::TIMESTAMP + 60 * 60,
128  self::TIMESTAMP + 60 * 60 + 60 * 60 * 24
129  ],
130  'once a day at 0:00' => [
131  '0 0 * * *',
132  self::TIMESTAMP,
133  self::TIMESTAMP + 60 * 60 * 24,
134  self::TIMESTAMP + 60 * 60 * 24 * 2
135  ],
136  'once a month' => [
137  '0 0 4 * *',
138  self::TIMESTAMP,
139  self::TIMESTAMP + 60 * 60 * 24 * 3,
140  self::TIMESTAMP + 60 * 60 * 24 * 3 + 60 * 60 * 24 * 31
141  ],
142  'once every Saturday' => [
143  '0 0 * * sat',
144  self::TIMESTAMP,
145  self::TIMESTAMP + 60 * 60 * 24,
146  self::TIMESTAMP + 60 * 60 * 24 + 60 * 60 * 24 * 7
147  ],
148  'once every day in February' => [
149  '0 0 * feb *',
150  self::TIMESTAMP,
151  self::TIMESTAMP + 60 * 60 * 24 * 31,
152  self::TIMESTAMP + 60 * 60 * 24 * 31 + 60 * 60 * 24
153  ],
154  'day of week and day of month restricted, next match in day of month field' => [
155  '0 0 2 * sun',
156  self::TIMESTAMP,
157  self::TIMESTAMP + 60 * 60 * 24,
158  self::TIMESTAMP + 60 * 60 * 24 + 60 * 60 * 24
159  ],
160  'day of week and day of month restricted, next match in day of week field' => [
161  '0 0 3 * sat',
162  self::TIMESTAMP,
163  self::TIMESTAMP + 60 * 60 * 24,
164  self::TIMESTAMP + 60 * 60 * 24 + 60 * 60 * 24
165  ],
166  'list of minutes' => [
167  '2,4 * * * *',
168  self::TIMESTAMP,
169  self::TIMESTAMP + 120,
170  self::TIMESTAMP + 240
171  ],
172  'list of hours' => [
173  '0 2,4 * * *',
174  self::TIMESTAMP,
175  self::TIMESTAMP + 60 * 60 * 2,
176  self::TIMESTAMP + 60 * 60 * 4
177  ],
178  ];
179  }
180 
185  {
186  return [
187  'every first day of month' => [
188  '0 0 1 * *',
189  self::TIMESTAMP,
190  '01-02-2010',
191  '01-03-2010',
192  ],
193  'once every February' => [
194  '0 0 1 feb *',
195  self::TIMESTAMP,
196  '01-02-2010',
197  '01-02-2011',
198  ],
199  'once every Friday February' => [
200  '0 0 * feb fri',
201  self::TIMESTAMP,
202  '05-02-2010',
203  '12-02-2010',
204  ],
205  'first day in February and every Friday' => [
206  '0 0 1 feb fri',
207  self::TIMESTAMP,
208  '01-02-2010',
209  '05-02-2010',
210  ],
211  '29th February leap year' => [
212  '0 0 29 feb *',
213  self::TIMESTAMP,
214  '29-02-2012',
215  '29-02-2016',
216  ],
217  'list of days in month' => [
218  '0 0 2,4 * *',
219  self::TIMESTAMP,
220  '02-01-2010',
221  '04-01-2010',
222  ],
223  'list of month' => [
224  '0 0 1 2,3 *',
225  self::TIMESTAMP,
226  '01-02-2010',
227  '01-03-2010',
228  ],
229  'list of days of weeks' => [
230  '0 0 * * 2,4',
231  self::TIMESTAMP,
232  '05-01-2010',
233  '07-01-2010',
234  ]
235  ];
236  }
237 
245  public function calculateNextValueDeterminesCorrectNextTimestamp($cronCommand, $startTimestamp, $expectedTimestamp)
246  {
247  $instance = new CronCommand($cronCommand, $startTimestamp);
248  $instance->calculateNextValue();
249  $this->assertSame($expectedTimestamp, $instance->getTimestamp());
250  }
251 
259  public function calculateNextValueDeterminesCorrectNextCalculatedTimestamp($cronCommand, $startTimestamp, $expectedTimestamp)
260  {
261  $instance = new CronCommand($cronCommand, $startTimestamp);
262  $instance->calculateNextValue();
263  $this->assertSame(strtotime($expectedTimestamp), $instance->getTimestamp());
264  }
265 
274  public function calculateNextValueDeterminesCorrectNextTimestampOnConsecutiveCall($cronCommand, $startTimestamp, $firstTimestamp, $secondTimestamp)
275  {
276  $instance = new CronCommand($cronCommand, $firstTimestamp);
277  $instance->calculateNextValue();
278  $this->assertSame($secondTimestamp, $instance->getTimestamp());
279  }
280 
289  public function calculateNextValueDeterminesCorrectNextCalculatedTimestampOnConsecutiveCall($cronCommand, $startTimestamp, $firstTimestamp, $secondTimestamp)
290  {
291  $instance = new CronCommand($cronCommand, strtotime($firstTimestamp));
292  $instance->calculateNextValue();
293  $this->assertSame(strtotime($secondTimestamp), $instance->getTimestamp());
294  }
295 
300  {
301  $backupTimezone = date_default_timezone_get();
302  date_default_timezone_set('Europe/Berlin');
303  $instance = new CronCommand('* 3 28 mar *', self::TIMESTAMP);
304  $instance->calculateNextValue();
305  date_default_timezone_set($backupTimezone);
306  $this->assertSame(1269741600, $instance->getTimestamp());
307  }
308 
313  {
314  $this->expectException(\RuntimeException::class);
315  $this->expectExceptionCode(1291501280);
316  $instance = new CronCommand('* * 31 apr *', self::TIMESTAMP);
317  $instance->calculateNextValue();
318  }
319 
323  public function getTimestampReturnsInteger()
324  {
325  $instance = new CronCommand('* * * * *');
326  $this->assertInternalType(\PHPUnit\Framework\Constraint\IsType::TYPE_INT, $instance->getTimestamp());
327  }
328 
333  {
334  $instance = new CronCommand('* * * * *');
335  $this->assertInternalType(\PHPUnit\Framework\Constraint\IsType::TYPE_ARRAY, $instance->getCronCommandSections());
336  }
337 }
calculateNextValueDeterminesCorrectNextCalculatedTimestampOnConsecutiveCall($cronCommand, $startTimestamp, $firstTimestamp, $secondTimestamp)
calculateNextValueDeterminesCorrectNextTimestamp($cronCommand, $startTimestamp, $expectedTimestamp)
calculateNextValueDeterminesCorrectNextTimestampOnConsecutiveCall($cronCommand, $startTimestamp, $firstTimestamp, $secondTimestamp)
calculateNextValueDeterminesCorrectNextCalculatedTimestamp($cronCommand, $startTimestamp, $expectedTimestamp)