ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
CronJobScheduleTest.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 
28 class CronJobScheduleTest extends TestCase
29 {
31 
33 
34  private function getJob(
35  bool $has_flexible_schedule,
36  CronJobScheduleType $default_schedule_type,
37  ?int $default_schedule_value,
38  CronJobScheduleType $schedule_type,
39  ?int $schedule_value
40  ): ilCronJob {
41  $job_instance = new class ($has_flexible_schedule, $default_schedule_type, $default_schedule_value, $schedule_type, $schedule_value) extends ilCronJob {
42  public function __construct(
43  private readonly bool $has_flexible_schedule,
44  private readonly CronJobScheduleType $default_schedule_type,
45  private readonly ?int $default_schedule_value,
46  CronJobScheduleType $schedule_type,
47  ?int $schedule_value
48  ) {
49  $this->schedule_type = $schedule_type;
50  $this->schedule_value = $schedule_value;
51  }
52 
53  public function getId(): string
54  {
55  return 'phpunit';
56  }
57 
58  public function getTitle(): string
59  {
60  return 'phpunit';
61  }
62 
63  public function getDescription(): string
64  {
65  return 'phpunit';
66  }
67 
68  public function hasAutoActivation(): bool
69  {
70  return false;
71  }
72 
73  public function hasFlexibleSchedule(): bool
74  {
75  return $this->has_flexible_schedule;
76  }
77 
78  public function getDefaultScheduleType(): CronJobScheduleType
79  {
80  return $this->default_schedule_type;
81  }
82 
83  public function getDefaultScheduleValue(): ?int
84  {
85  return $this->default_schedule_value;
86  }
87 
88  public function run(): ilCronJobResult
89  {
90  return new ilCronJobResult();
91  }
92  };
93 
94  $job_instance->setDateTimeProvider(function (): DateTimeImmutable {
95  return $this->now;
96  });
97 
98  return $job_instance;
99  }
100 
101  public function jobProvider(): array
102  {
103  // Can't be moved to setUp(), because the data provider is executed before the tests are executed
104  $this->now = new DateTimeImmutable('@' . time());
105 
106  $offset = (((int) $this->now->format('n')) - 1) % 3;
107  $this->this_quarter_start = $this->now->modify("first day of -$offset month midnight");
108 
109  return [
110  'Manual Run is Always Due' => [
111  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null),
112  true,
113  null,
114  CronJobScheduleType::SCHEDULE_TYPE_DAILY,
115  null,
116  true
117  ],
118  'Job Without Any Run is Always Due' => [
119  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null),
120  false,
121  null,
122  CronJobScheduleType::SCHEDULE_TYPE_DAILY,
123  null,
124  true
125  ],
126  'Daily Schedule / Did not run Today' => [
127  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null),
128  false,
129  $this->now->modify('-1 day'),
130  CronJobScheduleType::SCHEDULE_TYPE_DAILY,
131  null,
132  true
133  ],
134  'Daily Schedule / Did run Today' => [
135  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null, CronJobScheduleType::SCHEDULE_TYPE_DAILY, null),
136  false,
137  $this->now,
138  CronJobScheduleType::SCHEDULE_TYPE_DAILY,
139  null,
140  false
141  ],
142  'Weekly Schedule / Did not run this Week' => [
143  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
144  false,
145  $this->now->modify('-1 week'),
146  CronJobScheduleType::SCHEDULE_TYPE_WEEKLY,
147  null,
148  true
149  ],
150  'Weekly Schedule / Did run this Week' => [
151  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
152  false,
153  $this->now->modify('monday this week'),
154  CronJobScheduleType::SCHEDULE_TYPE_WEEKLY,
155  null,
156  false
157  ],
158  'Monthly Schedule / Did not run this Month' => [
159  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_MONTHLY, null, CronJobScheduleType::SCHEDULE_TYPE_MONTHLY, null),
160  false,
161  $this->now->modify('last day of last month'),
162  CronJobScheduleType::SCHEDULE_TYPE_MONTHLY,
163  null,
164  true
165  ],
166  'Monthly Schedule / Did run this Month' => [
167  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_MONTHLY, null, CronJobScheduleType::SCHEDULE_TYPE_MONTHLY, null),
168  false,
169  $this->now->modify('first day of this month'),
170  CronJobScheduleType::SCHEDULE_TYPE_MONTHLY,
171  null,
172  false
173  ],
174  'Yearly Schedule / Did not run this Year' => [
176  false,
177  $this->now->modify('-1 year'),
179  null,
180  true
181  ],
182  'Yearly Schedule / Did run this Year' => [
184  false,
185  $this->now->modify('first day of January this year'),
187  null,
188  false
189  ],
190  'Quarterly Schedule / Did not run this Quarter' => [
191  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_QUARTERLY, null, CronJobScheduleType::SCHEDULE_TYPE_QUARTERLY, null),
192  false,
193  $this->this_quarter_start->modify('-1 seconds'),
194  CronJobScheduleType::SCHEDULE_TYPE_QUARTERLY,
195  null,
196  true
197  ],
198  'Quarterly Schedule / Did run this Quarter' => [
199  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_QUARTERLY, null, CronJobScheduleType::SCHEDULE_TYPE_QUARTERLY, null),
200  false,
201  $this->this_quarter_start->modify('+30 seconds'),
202  CronJobScheduleType::SCHEDULE_TYPE_QUARTERLY,
203  null,
204  false
205  ],
206  'Minutely Schedule / Did not run this Minute' => [
207  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_IN_MINUTES, 1, CronJobScheduleType::SCHEDULE_TYPE_IN_MINUTES, 1),
208  false,
209  $this->now->modify('-1 minute'),
210  CronJobScheduleType::SCHEDULE_TYPE_IN_MINUTES,
211  1,
212  true
213  ],
214  'Minutely Schedule / Did run this Minute' => [
215  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_IN_MINUTES, 1, CronJobScheduleType::SCHEDULE_TYPE_IN_MINUTES, 1),
216  false,
217  $this->now->modify('-30 seconds'),
218  CronJobScheduleType::SCHEDULE_TYPE_IN_MINUTES,
219  1,
220  false
221  ],
222  'Hourly Schedule / Did not run this Hour' => [
223  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_IN_HOURS, 7, CronJobScheduleType::SCHEDULE_TYPE_IN_HOURS, 7),
224  false,
225  $this->now->modify('-7 hours'),
226  CronJobScheduleType::SCHEDULE_TYPE_IN_HOURS,
227  7,
228  true
229  ],
230  'Hourly Schedule / Did run this Hour' => [
231  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_IN_HOURS, 7, CronJobScheduleType::SCHEDULE_TYPE_IN_HOURS, 7),
232  false,
233  $this->now->modify('-7 hours +30 seconds'),
234  CronJobScheduleType::SCHEDULE_TYPE_IN_HOURS,
235  7,
236  false
237  ],
238  'Every 5 Days Schedule / Did not run for 5 Days' => [
239  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_IN_DAYS, 5, CronJobScheduleType::SCHEDULE_TYPE_IN_DAYS, 5),
240  false,
241  $this->now->modify('-5 days'),
242  CronJobScheduleType::SCHEDULE_TYPE_IN_DAYS,
243  5,
244  true
245  ],
246  'Every 5 Days Schedule / Did run withing the last 5 Days' => [
247  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_IN_DAYS, 5, CronJobScheduleType::SCHEDULE_TYPE_IN_DAYS, 5),
248  false,
249  $this->now->modify('-4 days'),
250  CronJobScheduleType::SCHEDULE_TYPE_IN_DAYS,
251  5,
252  false
253  ]
254  ];
255  }
256 
260  public function testSchedule(
261  ilCronJob $job_instance,
262  bool $is_manual_run,
263  ?DateTimeImmutable $last_run_datetime,
264  CronJobScheduleType $schedule_type,
265  ?int $schedule_value,
266  bool $should_be_due
267  ): void {
268  $this->assertSame(
269  $should_be_due,
270  $job_instance->isDue($last_run_datetime, $schedule_type, $schedule_value, $is_manual_run),
271  'Last run: ' . ($last_run_datetime ? $last_run_datetime->format(DATE_ATOM) : 'never')
272  );
273  }
274 
276  {
277  yield 'Different Week' => [
278  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
279  function (): DateTimeImmutable {
280  $this->now = new DateTimeImmutable('@1672570104'); // Sun Jan 01 2023 10:48:24 GMT+0000 (year: 2023 / week: 52)
281 
282  return $this->now->modify('-1 week'); // Sun Dec 25 2022 10:48:24 GMT+0000 (year: 2022 / week: 51)
283  },
284  true
285  ];
286 
287  yield 'Same Week and Year, but different Month: December (now) and January (Last run)' => [
288  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
289  function (): DateTimeImmutable {
290  $this->now = new DateTimeImmutable('@1703669703'); // Wed Dec 27 2023 09:35:03 GMT+0000 (year: 2023 / week: 52 / month: 12)
291 
292  return new DateTimeImmutable('@1672570104'); // Sun Jan 01 2023 10:48:24 GMT+0000 (year: 2023 / week: 52 / month: 1)
293  },
294  true
295  ];
296 
297  yield 'Same Week and Year and same Month: January' => [
298  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
299  function (): DateTimeImmutable {
300  $this->now = new DateTimeImmutable('@1704188103'); // Tue Jan 02 2024 09:35:03 GMT+0000 (year: 2024 / week: 1 / month: 1)
301 
302  return $this->now->modify('-1 day'); // Mon Jan 01 2024 09:35:03 GMT+0000 (year: 2024 / week: 1 / month: 1)
303  },
304  false
305  ];
306 
307  yield 'Same Week (52nd), but Year Difference > 1' => [
308  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
309  function (): DateTimeImmutable {
310  $this->now = new DateTimeImmutable('@1672570104'); // Sun Jan 01 2023 10:48:24 GMT+0000 (year: 2023 / week: 52)
311 
312  return $this->now->modify('tuesday this week')->modify('-1 year'); // Mon Dec 27 2021 10:48:24 GMT+0000 (year: 2021 / week: 52)
313  },
314  true
315  ];
316 
317  yield 'Same Week (52nd) in different Years, but Turn of the Year' => [
318  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
319  function (): DateTimeImmutable {
320  $this->now = new DateTimeImmutable('@1672570104'); // Sun Jan 01 2023 10:48:24 GMT+0000 (year: 2023 / week: 52 / month: 1)
321 
322  return $this->now->modify('monday this week'); // Mon Dec 26 2022 10:48:24 GMT+0000 (year: 2022 / week: 52 / month: 12)
323  },
324  false
325  ];
326 
327  yield 'Same Week (52nd) in different Years, but not Turn of the Year' => [
328  $this->getJob(true, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null, CronJobScheduleType::SCHEDULE_TYPE_WEEKLY, null),
329  function (): DateTimeImmutable {
330  $this->now = new DateTimeImmutable('@1703669703'); // Wed Dec 27 2023 09:35:03 GMT+0000 (year: 2023 / week: 52 / month: 12)
331 
332  return new DateTimeImmutable('@1672012800'); // Mon Dec 26 2022 00:00:00 GMT+0000 (year: 2022 / week: 52 / month: 12)
333  },
334  true
335  ];
336  }
337 
342  public function testWeeklySchedules(
343  ilCronJob $job_instance,
344  callable $last_run_datetime_provider,
345  bool $should_be_due
346  ): void {
347  $last_run_datetime = $last_run_datetime_provider();
348 
349  $this->assertSame(
350  $should_be_due,
351  $job_instance->isDue(
352  $last_run_datetime,
353  $job_instance->getScheduleType(),
354  $job_instance->getScheduleValue(),
355  false
356  ),
357  'Last run: ' . $last_run_datetime->format(DATE_ATOM)
358  );
359  }
360 }
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
testSchedule(ilCronJob $job_instance, bool $is_manual_run, ?DateTimeImmutable $last_run_datetime, CronJobScheduleType $schedule_type, ?int $schedule_value, bool $should_be_due)
jobProvider
isDue(?DateTimeImmutable $last_run, ?CronJobScheduleType $schedule_type, ?int $schedule_value, bool $is_manually_executed=false)
testWeeklySchedules(ilCronJob $job_instance, callable $last_run_datetime_provider, bool $should_be_due)
weeklyScheduleProvider
DateTimeImmutable $this_quarter_start
__construct(VocabulariesInterface $vocabularies)
DateTimeImmutable $now
Class CronJobScheduleTest.
getJob(bool $has_flexible_schedule, CronJobScheduleType $default_schedule_type, ?int $default_schedule_value, CronJobScheduleType $schedule_type, ?int $schedule_value)
getScheduleValue()
Get current schedule value (if flexible)
getScheduleType()
Get current schedule type (if flexible)