Skip to content
Snippets Groups Projects
Commit 9ed4d370 authored by Andreas Kienast's avatar Andreas Kienast Committed by Nikita Hovratov
Browse files

[BUGFIX] Handle roll-over of dates in `RotatingFileWriterTest`

In the test class `RotatingFileWriterTest`, the `MONTHLY` and `YEARLY`
cases for `writingLogWithExpiredLatestRotationInTimeFrameRotates` may
fail as it tries to create a mock file that needs rotation with a
broken date.

It is expected to create a file with a date of the previous period
that's tested. However, at the end of uneven months or each Feb. 29th
this will heavily fail due to PHP's automatic roll-over to the next
valid date. We'd need a fallback to the latest valid date here.

The aforementioned test now has a special handling in place in case
either `MONTHLY` or `YEARLY` are tested – the date is modified to go
back to the first day of the respective period and then either set the
current day OR the latest days in that period, whatever fits.

Resolves: #103509
Releases: main
Change-Id: Ic60c3056ed31933ff7be3af196ba08ed92f04855
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83630


Reviewed-by: default avatarNikita Hovratov <nikita.h@live.de>
Tested-by: default avatarcore-ci <typo3@b13.com>
Tested-by: default avatarNikita Hovratov <nikita.h@live.de>
Tested-by: default avatarOliver Klee <typo3-coding@oliverklee.de>
Reviewed-by: default avatarOliver Klee <typo3-coding@oliverklee.de>
parent d64c5fcd
Branches
Tags
No related merge requests found
......@@ -131,11 +131,32 @@ final class RotatingFileWriterTest extends UnitTestCase
#[Test]
public function writingLogWithExpiredLatestRotationInTimeFrameRotates(Interval $interval): void
{
// Helper variable to ensure the next rotation interval kicks in
$boost = 100;
$rotationDate = (new \DateTime('@' . (time() - $boost)))
->sub(new \DateInterval($interval->getDateInterval()))
->format('YmdHis');
$rotationDateModifierClosure = match ($interval) {
Interval::MONTHLY, Interval::YEARLY => static function (\DateTimeImmutable $rotationDate) use ($interval): \DateTimeImmutable {
// This is great – when subtracting 1 month or 1 year, it may happen that the result would be invalid:
// e.g. 2024-03-30 -1 month -> 2024-02-30, 2024-05-31 -1 month -> 2024-04-31, 2028-02-29 -1 year -> 2027-02-29, etc.
// PHP thankfully catches this and rolls over to the next(!) valid date:
// e.g. 2024-03-30 -1 month -> 2024-03-01, 2024-05-31 -1 month -> 2024-05-01, 2028-02-29 -1 year -> 2027-03-01, etc.
// However, this is not the desired result in this case when SUBTRACTING a month as the previous(!!) valid date is required.
// For this reason, a custom handling in case of months and years is in place that goes back in time to the first day of
// the given period, and sets the current day or the last day of the resulting period, whatever fits:
// e.g. 2024-03-30 -1 month -> 2024-02-29, 2024-05-12 -1 month -> 2024-04-12, 2028-02-29 -1 year -> 2027-02-28, etc.
if ($interval === Interval::MONTHLY) {
$firstDayOfModifier = 'first day of -1 month';
} else {
$firstDayOfModifier = 'first day of -1 year';
}
$currentDay = $rotationDate->format('j');
$rotationDate = $rotationDate->modify($firstDayOfModifier);
$totalDays = $rotationDate->format('t');
return $rotationDate->modify('+' . (min($currentDay, $totalDays) - 1) . ' days');
},
default => static function (\DateTimeImmutable $rotationDate) use ($interval): \DateTimeImmutable {
return $rotationDate->sub(new \DateInterval($interval->getDateInterval()));
},
};
$rotationDate = $rotationDateModifierClosure(new \DateTimeImmutable('@' . time()))->format('YmdHis');
$logFileName = $this->getDefaultFileName();
file_put_contents($logFileName, 'fooo');
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment