[TASK] Stabilize scheduler tests and activate in travis
[Packages/TYPO3.CMS.git] / typo3 / sysext / scheduler / Tests / Unit / CronCommand / CronCommandTest.php
1 <?php
2 namespace TYPO3\CMS\Scheduler\Tests\Unit\CronCommand;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2011 Christian Kuhn <lolli@schwarzbu.ch>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26 /**
27 * Testcase for class "tx_scheduler_CronCmd"
28 *
29 * @package TYPO3
30 * @subpackage tx_scheduler
31 * @author Christian Kuhn <lolli@schwarzbu.ch>
32 */
33 class CronCommandTest extends \tx_phpunit_testcase {
34
35 /**
36 * @const integer timestamp of 1.1.2010 0:00 (Friday), timezone UTC/GMT
37 */
38 const TIMESTAMP = 1262304000;
39
40 /**
41 * @var string Selected timezone backup
42 */
43 protected $timezoneBackup = '';
44
45 /**
46 * We're fiddling with hard timestamps in the tests, but time methods in
47 * the system under test do use timezone settings. Therefore we backup the
48 * current timezone setting, set it to UTC explicitly and reconstitute it
49 * again in tearDown()
50 */
51 public function setUp() {
52 $this->timezoneBackup = date_default_timezone_get();
53 date_default_timezone_set('UTC');
54 }
55
56 public function tearDown() {
57 date_default_timezone_set($this->timezoneBackup);
58 }
59
60 /**
61 * @test
62 */
63 public function constructorSetsNormalizedCronCommandSections() {
64 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('2-3 * * * *');
65 $this->assertSame(array('2,3', '*', '*', '*', '*'), $instance->getCronCommandSections());
66 }
67
68 /**
69 * @test
70 * @expectedException InvalidArgumentException
71 */
72 public function constructorThrowsExceptionForInvalidCronCommand() {
73 new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('61 * * * *');
74 }
75
76 /**
77 * @test
78 */
79 public function constructorSetsTimestampToNowPlusOneMinuteRoundedDownToSixtySeconds() {
80 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('* * * * *');
81 $currentTime = time();
82 $expectedTime = $currentTime - ($currentTime % 60) + 60;
83 $this->assertSame($expectedTime, $instance->getTimestamp());
84 }
85
86 /**
87 * @test
88 */
89 public function constructorSetsTimestampToGivenTimestampPlusSixtySeconds() {
90 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('* * * * *', self::TIMESTAMP);
91 $this->assertSame(self::TIMESTAMP + 60, $instance->getTimestamp());
92 }
93
94 /**
95 * @test
96 */
97 public function constructorSetsTimestampToGiveTimestampRoundedDownToSixtySeconds() {
98 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('* * * * *', self::TIMESTAMP + 1);
99 $this->assertSame(self::TIMESTAMP + 60, $instance->getTimestamp());
100 }
101
102 /**
103 * @return array
104 */
105 static public function expectedTimestampDataProvider() {
106 return array(
107 'every minute' => array(
108 '* * * * *',
109 self::TIMESTAMP,
110 self::TIMESTAMP + 60,
111 self::TIMESTAMP + 120
112 ),
113 'once an hour at 1' => array(
114 '1 * * * *',
115 self::TIMESTAMP,
116 self::TIMESTAMP + 60,
117 (self::TIMESTAMP + 60) + 60 * 60
118 ),
119 'once an hour at 0' => array(
120 '0 * * * *',
121 self::TIMESTAMP,
122 self::TIMESTAMP + 60 * 60,
123 (self::TIMESTAMP + 60 * 60) + 60 * 60
124 ),
125 'once a day at 1:00' => array(
126 '0 1 * * *',
127 self::TIMESTAMP,
128 self::TIMESTAMP + 60 * 60,
129 (self::TIMESTAMP + 60 * 60) + (60 * 60) * 24
130 ),
131 'once a day at 0:00' => array(
132 '0 0 * * *',
133 self::TIMESTAMP,
134 self::TIMESTAMP + (60 * 60) * 24,
135 self::TIMESTAMP + ((60 * 60) * 24) * 2
136 ),
137 'once a month' => array(
138 '0 0 4 * *',
139 self::TIMESTAMP,
140 self::TIMESTAMP + ((60 * 60) * 24) * 3,
141 (self::TIMESTAMP + ((60 * 60) * 24) * 3) + ((60 * 60) * 24) * 31
142 ),
143 'once every Saturday' => array(
144 '0 0 * * sat',
145 self::TIMESTAMP,
146 self::TIMESTAMP + (60 * 60) * 24,
147 (self::TIMESTAMP + (60 * 60) * 24) + ((60 * 60) * 24) * 7
148 ),
149 'once every day in February' => array(
150 '0 0 * feb *',
151 self::TIMESTAMP,
152 self::TIMESTAMP + ((60 * 60) * 24) * 31,
153 (self::TIMESTAMP + ((60 * 60) * 24) * 31) + (60 * 60) * 24
154 ),
155 'day of week and day of month restricted, next match in day of month field' => array(
156 '0 0 2 * sun',
157 self::TIMESTAMP,
158 self::TIMESTAMP + (60 * 60) * 24,
159 (self::TIMESTAMP + (60 * 60) * 24) + (60 * 60) * 24
160 ),
161 'day of week and day of month restricted, next match in day of week field' => array(
162 '0 0 3 * sat',
163 self::TIMESTAMP,
164 self::TIMESTAMP + (60 * 60) * 24,
165 (self::TIMESTAMP + (60 * 60) * 24) + (60 * 60) * 24
166 ),
167 'list of minutes' => array(
168 '2,4 * * * *',
169 self::TIMESTAMP,
170 self::TIMESTAMP + 120,
171 self::TIMESTAMP + 240
172 ),
173 'list of hours' => array(
174 '0 2,4 * * *',
175 self::TIMESTAMP,
176 self::TIMESTAMP + (60 * 60) * 2,
177 self::TIMESTAMP + (60 * 60) * 4
178 ),
179 );
180 }
181
182 /**
183 * @return array
184 */
185 static public function expectedCalculatedTimestampDataProvider() {
186 return array(
187 'every first day of month' => array(
188 '0 0 1 * *',
189 self::TIMESTAMP,
190 '01-02-2010',
191 '01-03-2010',
192 ),
193 'once every February' => array(
194 '0 0 1 feb *',
195 self::TIMESTAMP,
196 '01-02-2010',
197 '01-02-2011',
198 ),
199 'once every Friday February' => array(
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' => array(
206 '0 0 1 feb fri',
207 self::TIMESTAMP,
208 '01-02-2010',
209 '05-02-2010',
210 ),
211 '29th February leap year' => array(
212 '0 0 29 feb *',
213 self::TIMESTAMP,
214 '29-02-2012',
215 '29-02-2016',
216 ),
217 'list of days in month' => array(
218 '0 0 2,4 * *',
219 self::TIMESTAMP,
220 '02-01-2010',
221 '04-01-2010',
222 ),
223 'list of month' => array(
224 '0 0 1 2,3 *',
225 self::TIMESTAMP,
226 '01-02-2010',
227 '01-03-2010',
228 ),
229 'list of days of weeks' => array(
230 '0 0 * * 2,4',
231 self::TIMESTAMP,
232 '05-01-2010',
233 '07-01-2010',
234 )
235 );
236 }
237
238 /**
239 * @test
240 * @dataProvider expectedTimestampDataProvider
241 * @param string $cronCommand Cron command
242 * @param integer $startTimestamp Timestamp for start of calculation
243 * @param integer $expectedTimestamp Expected result (next time of execution)
244 */
245 public function calculateNextValueDeterminesCorrectNextTimestamp($cronCommand, $startTimestamp, $expectedTimestamp) {
246 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand($cronCommand, $startTimestamp);
247 $instance->calculateNextValue();
248 $this->assertSame($expectedTimestamp, $instance->getTimestamp());
249 }
250
251 /**
252 * @test
253 * @dataProvider expectedCalculatedTimestampDataProvider
254 * @param string $cronCommand Cron command
255 * @param integer $startTimestamp Timestamp for start of calculation
256 * @param string $expectedTimestamp Expected result (next time of execution), to be feeded to strtotime
257 */
258 public function calculateNextValueDeterminesCorrectNextCalculatedTimestamp($cronCommand, $startTimestamp, $expectedTimestamp) {
259 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand($cronCommand, $startTimestamp);
260 $instance->calculateNextValue();
261 $this->assertSame(strtotime($expectedTimestamp), $instance->getTimestamp());
262 }
263
264 /**
265 * @test
266 * @dataProvider expectedTimestampDataProvider
267 * @param string $cronCommand Cron command
268 * @param integer $startTimestamp [unused] Timestamp for start of calculation
269 * @param integer $firstTimestamp Timestamp of the next execution
270 * @param integer $secondTimestamp Timestamp of the further execution
271 */
272 public function calculateNextValueDeterminesCorrectNextTimestampOnConsecutiveCall($cronCommand, $startTimestamp, $firstTimestamp, $secondTimestamp) {
273 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand($cronCommand, $firstTimestamp);
274 $instance->calculateNextValue();
275 $this->assertSame($secondTimestamp, $instance->getTimestamp());
276 }
277
278 /**
279 * @test
280 * @dataProvider expectedCalculatedTimestampDataProvider
281 * @param string $cronCommand Cron command
282 * @param integer $startTimestamp [unused] Timestamp for start of calculation
283 * @param string $firstTimestamp Timestamp of the next execution, to be feeded to strtotime
284 * @param string $secondTimestamp Timestamp of the further execution, to be feeded to strtotime
285 */
286 public function calculateNextValueDeterminesCorrectNextCalculatedTimestampOnConsecutiveCall($cronCommand, $startTimestamp, $firstTimestamp, $secondTimestamp) {
287 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand($cronCommand, strtotime($firstTimestamp));
288 $instance->calculateNextValue();
289 $this->assertSame(strtotime($secondTimestamp), $instance->getTimestamp());
290 }
291
292 /**
293 * @test
294 */
295 public function calculateNextValueDeterminesCorrectNextTimestampOnChangeToSummertime() {
296 $backupTimezone = date_default_timezone_get();
297 date_default_timezone_set('Europe/Berlin');
298 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('* 3 28 mar *', self::TIMESTAMP);
299 $instance->calculateNextValue();
300 date_default_timezone_set($backupTimezone);
301 $this->assertSame(1269741600, $instance->getTimestamp());
302 }
303
304 /**
305 * @test
306 * @expectedException RuntimeException
307 */
308 public function calculateNextValueThrowsExceptionWithImpossibleCronCommand() {
309 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('* * 31 apr *', self::TIMESTAMP);
310 $instance->calculateNextValue();
311 }
312
313 /**
314 * @test
315 */
316 public function getTimestampReturnsInteger() {
317 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('* * * * *');
318 $this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_INT, $instance->getTimestamp());
319 }
320
321 /**
322 * @test
323 */
324 public function getCronCommandSectionsReturnsArray() {
325 $instance = new \TYPO3\CMS\Scheduler\CronCommand\CronCommand('* * * * *');
326 $this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $instance->getCronCommandSections());
327 }
328
329 }
330
331
332 ?>