Download plugins/CoreAdminHome/tests/Integration/Commands/ResetInvalidationsTest.php from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 35.8 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreAdminHome/tests/Integration/Commands/ResetInvalidationsTest.php
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/plugins/CoreAdminHome/tests/Integration/Commands/ResetInvalidationsTest.php
-
curl -L -o ResetInvalidationsTest.php https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreAdminHome/tests/Integration/Commands/ResetInvalidationsTest.php
35.8 kB
| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| namespace Piwik\Plugins\CoreAdminHome\tests\Integration\Commands; | |
| use Monolog\Handler\AbstractProcessingHandler; | |
| use Piwik\Archive\ArchiveInvalidator; | |
| use Piwik\Common; | |
| use Piwik\Db; | |
| use Piwik\Period\Day; | |
| use Piwik\Period\Month; | |
| use Piwik\Period\Week; | |
| use Piwik\Period\Year; | |
| use Piwik\Tests\Framework\Fixture; | |
| use Piwik\Tests\Framework\TestCase\ConsoleCommandTestCase; | |
| /** | |
| * @group CoreAdminHome | |
| * @group CoreAdminHome_Integration | |
| */ | |
| class ResetInvalidationsTest extends ConsoleCommandTestCase | |
| { | |
| private static $captureHandler; | |
| public static function setUpBeforeClass(): void | |
| { | |
| parent::setUpBeforeClass(); | |
| Fixture::createWebsite('2012-01-01 00:00:00'); | |
| Fixture::createWebsite('2012-01-01 00:00:00'); | |
| Fixture::createWebsite('2012-01-01 00:00:00'); | |
| } | |
| public function setUp(): void | |
| { | |
| parent::setUp(); | |
| self::$captureHandler->messages = []; | |
| } | |
| protected function tearDown(): void | |
| { | |
| self::$captureHandler->messages = []; | |
| parent::tearDown(); | |
| } | |
| /** | |
| * @dataProvider getInvalidDates | |
| */ | |
| public function testCommandFailsWhenInvalidDatesAreUsed($newerThan, $olderThan, $expectedMessage) | |
| { | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '--newer-than' => $newerThan, | |
| '--older-than' => $olderThan, | |
| '--dry-run' => true, | |
| ]); | |
| $this->assertNotEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| self::assertStringContainsString($expectedMessage, $this->getLogOutput()); | |
| } | |
| public function getInvalidDates(): iterable | |
| { | |
| yield 'invalid newer than date' => [ | |
| 'inValid', '', 'Invalid value for --newer-than provided.', | |
| ]; | |
| yield 'invalid older than date' => [ | |
| '', 'inValid', 'Invalid value for --older-than provided.', | |
| ]; | |
| } | |
| /** | |
| * @dataProvider getDryRunTestData | |
| */ | |
| public function testDryRunOutput($parameters, $expectedOutput, $expectedChangeInProgressInvalidations) | |
| { | |
| $this->prepareInvalidations(); | |
| $inProgressInvalidationCount = $this->getInProgressInvalidationCount(); | |
| $code = $this->applicationTester->run(array_merge([ | |
| 'command' => 'core:reset-invalidations', | |
| '--dry-run' => true, | |
| ], $parameters)); | |
| $inProgressInvalidationCountAfterDryRun = $this->getInProgressInvalidationCount(); | |
| self::assertEquals($inProgressInvalidationCount, $inProgressInvalidationCountAfterDryRun); | |
| $this->assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| self::assertStringContainsString($expectedOutput, $this->applicationTester->getDisplay(true)); | |
| $code = $this->applicationTester->run(array_merge([ | |
| 'command' => 'core:reset-invalidations', | |
| ], $parameters)); | |
| $inProgressInvalidationCountAfterRun = $this->getInProgressInvalidationCount(); | |
| self::assertEquals($expectedChangeInProgressInvalidations, $inProgressInvalidationCountAfterDryRun - $inProgressInvalidationCountAfterRun); | |
| $this->assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| } | |
| public function getDryRunTestData(): iterable | |
| { | |
| yield 'no limitations returns everything' => [ | |
| [], | |
| "4 invalidations found: | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 2 | | 2024-12-30 | 2025-01-05 | 2 | 2025-01-01 19:15:01 | 2025-02-05 09:11:00 | host1 | 2333 | | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| | donec7445c35d0f9b340f5851df27a15c5ef.Actions | 1 | | 2025-01-01 | 2025-12-31 | 4 | 2025-01-01 16:00:02 | 2025-02-05 16:44:22 | anotherhost | 662 | | |
| | done.VisitsSummary | 3 | | 2025-02-01 | 2025-02-28 | 3 | 2025-02-20 19:15:01 | 2025-02-23 18:35:00 | random | 8558 | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 4, | |
| ]; | |
| yield 'limiting by all sites works as expected' => [ | |
| ['--idsite' => ['all']], | |
| "4 invalidations found: | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 2 | | 2024-12-30 | 2025-01-05 | 2 | 2025-01-01 19:15:01 | 2025-02-05 09:11:00 | host1 | 2333 | | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| | donec7445c35d0f9b340f5851df27a15c5ef.Actions | 1 | | 2025-01-01 | 2025-12-31 | 4 | 2025-01-01 16:00:02 | 2025-02-05 16:44:22 | anotherhost | 662 | | |
| | done.VisitsSummary | 3 | | 2025-02-01 | 2025-02-28 | 3 | 2025-02-20 19:15:01 | 2025-02-23 18:35:00 | random | 8558 | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 4, | |
| ]; | |
| yield 'limiting by site works as expected' => [ | |
| ['--idsite' => [1]], | |
| "2 invalidations found: | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| | donec7445c35d0f9b340f5851df27a15c5ef.Actions | 1 | | 2025-01-01 | 2025-12-31 | 4 | 2025-01-01 16:00:02 | 2025-02-05 16:44:22 | anotherhost | 662 | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 2, | |
| ]; | |
| yield 'limiting by another site works as expected' => [ | |
| ['--idsite' => [2]], | |
| "1 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 2 | | 2024-12-30 | 2025-01-05 | 2 | 2025-01-01 19:15:01 | 2025-02-05 09:11:00 | host1 | 2333 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 1, | |
| ]; | |
| yield 'limiting by multiple sites works as expected' => [ | |
| ['--idsite' => [1, 3]], | |
| "3 invalidations found: | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| | donec7445c35d0f9b340f5851df27a15c5ef.Actions | 1 | | 2025-01-01 | 2025-12-31 | 4 | 2025-01-01 16:00:02 | 2025-02-05 16:44:22 | anotherhost | 662 | | |
| | done.VisitsSummary | 3 | | 2025-02-01 | 2025-02-28 | 3 | 2025-02-20 19:15:01 | 2025-02-23 18:35:00 | random | 8558 | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 3, | |
| ]; | |
| yield 'limiting by a site without records works as expected' => [ | |
| ['--idsite' => [4]], | |
| "No invalidations found.", | |
| 0, | |
| ]; | |
| yield 'limiting by host works as expected' => [ | |
| ['--processing-host' => ['host1']], | |
| "2 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 2 | | 2024-12-30 | 2025-01-05 | 2 | 2025-01-01 19:15:01 | 2025-02-05 09:11:00 | host1 | 2333 | | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 2, | |
| ]; | |
| yield 'limiting by multiple hosts works as expected' => [ | |
| ['--processing-host' => ['host1', 'random']], | |
| "3 invalidations found: | |
| +--------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +--------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 2 | | 2024-12-30 | 2025-01-05 | 2 | 2025-01-01 19:15:01 | 2025-02-05 09:11:00 | host1 | 2333 | | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| | done.VisitsSummary | 3 | | 2025-02-01 | 2025-02-28 | 3 | 2025-02-20 19:15:01 | 2025-02-23 18:35:00 | random | 8558 | | |
| +--------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 3, | |
| ]; | |
| yield 'limiting by hosts without records works as expected' => [ | |
| ['--processing-host' => ['unknown']], | |
| "No invalidations found.", | |
| 0, | |
| ]; | |
| yield 'limiting by newer-than works as expected' => [ | |
| ['--newer-than' => '2025-02-05 12:00:00'], | |
| "2 invalidations found: | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | donec7445c35d0f9b340f5851df27a15c5ef.Actions | 1 | | 2025-01-01 | 2025-12-31 | 4 | 2025-01-01 16:00:02 | 2025-02-05 16:44:22 | anotherhost | 662 | | |
| | done.VisitsSummary | 3 | | 2025-02-01 | 2025-02-28 | 3 | 2025-02-20 19:15:01 | 2025-02-23 18:35:00 | random | 8558 | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 2, | |
| ]; | |
| yield 'limiting by older-than works as expected' => [ | |
| ['--older-than' => '2025-02-05 12:00:00'], | |
| "2 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 2 | | 2024-12-30 | 2025-01-05 | 2 | 2025-01-01 19:15:01 | 2025-02-05 09:11:00 | host1 | 2333 | | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 2, | |
| ]; | |
| yield 'limiting by older-than and newer-than works as expected' => [ | |
| ['--newer-than' => '2025-02-05 12:00:00', '--older-than' => '2025-02-21 12:00:00'], | |
| "1 invalidations found: | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | donec7445c35d0f9b340f5851df27a15c5ef.Actions | 1 | | 2025-01-01 | 2025-12-31 | 4 | 2025-01-01 16:00:02 | 2025-02-05 16:44:22 | anotherhost | 662 | | |
| +----------------------------------------------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 1, | |
| ]; | |
| yield 'limiting by everything works as expected' => [ | |
| ['--newer-than' => '2025-02-05 08:00:00', '--older-than' => '2025-02-21 12:00:00', '--idsite' => ['1'], '--processing-host' => ['host1']], | |
| "1 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| ", | |
| 1, | |
| ]; | |
| } | |
| public function testDuplicateInvalidationIsRemovedOnReset() | |
| { | |
| $invalidationsToInsert = [ | |
| [ | |
| 'idarchive' => 7, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-01 16:00:00', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, 'ts_started' => '2025-02-05 11:30:00', 'processing_host' => 'host1', 'process_id' => 1256, | |
| ], | |
| [ | |
| 'idarchive' => null, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-03 02:55:55', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_QUEUED, | |
| 'report' => null, 'ts_started' => null, 'processing_host' => null, 'process_id' => null, | |
| ], | |
| ]; | |
| $this->insertInvalidations($invalidationsToInsert); | |
| $inProgressInvalidationCount = $this->getInProgressInvalidationCount(); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '--dry-run' => true, | |
| ]); | |
| $inProgressInvalidationCountAfterDryRun = $this->getInProgressInvalidationCount(); | |
| self::assertEquals($inProgressInvalidationCount, $inProgressInvalidationCountAfterDryRun); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $expectedOutput = '1 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| '; | |
| self::assertStringContainsString($expectedOutput, $this->applicationTester->getDisplay(true)); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '-vvv' => true, | |
| ]); | |
| self::assertEquals(0, $this->getInProgressInvalidationCount()); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $rows = Db::fetchAll('SELECT * FROM ' . Common::prefixTable('archive_invalidations')); | |
| self::assertEquals(1, count($rows)); | |
| // expected invalidation date from second record, as first one should be removed instead of reset | |
| self::assertEquals('2025-01-03 02:55:55', $rows[0]['ts_invalidated']); | |
| self::assertStringContainsString('Found duplicate invalidation for params (name = done, idsite = 1, date1 = 2025-01-01, date2 = 2025-01-01, period = 1, report = ). Removing invalidation 1 instead of resetting it.', $this->getLogOutput()); | |
| } | |
| public function testDuplicateInvalidationIsRemovedOnResetWhenOtherOneStartedAfterInvalidationDate() | |
| { | |
| $invalidationsToInsert = [ | |
| [ | |
| 'idarchive' => 7, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-01 16:00:00', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, 'ts_started' => '2025-02-05 11:30:00', 'processing_host' => 'host1', 'process_id' => 1256, | |
| ], | |
| [ | |
| 'idarchive' => null, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-03 02:55:55', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, 'ts_started' => '2025-01-02 08:00:00', 'processing_host' => 'host4', 'process_id' => 22555, | |
| ], | |
| ]; | |
| $this->insertInvalidations($invalidationsToInsert); | |
| $inProgressInvalidationCount = $this->getInProgressInvalidationCount(); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '--processing-host' => ['host1'], | |
| '--dry-run' => true, | |
| ]); | |
| $inProgressInvalidationCountAfterDryRun = $this->getInProgressInvalidationCount(); | |
| self::assertEquals($inProgressInvalidationCount, $inProgressInvalidationCountAfterDryRun); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $expectedOutput = '1 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| '; | |
| self::assertStringContainsString($expectedOutput, $this->applicationTester->getDisplay(true)); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '--processing-host' => ['host1'], | |
| '-vvv' => true, | |
| ]); | |
| self::assertEquals(1, $this->getInProgressInvalidationCount()); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $rows = Db::fetchAll('SELECT * FROM ' . Common::prefixTable('archive_invalidations')); | |
| self::assertEquals(1, count($rows)); | |
| // expected invalidation date from second record, as first one should be removed instead of reset | |
| self::assertEquals('2025-01-03 02:55:55', $rows[0]['ts_invalidated']); | |
| self::assertStringContainsString('Found duplicate invalidation for params (name = done, idsite = 1, date1 = 2025-01-01, date2 = 2025-01-01, period = 1, report = ). Removing invalidation 1 instead of resetting it.', $this->getLogOutput()); | |
| } | |
| public function testDuplicateInvalidationIsOnlyResetWhenOtherOneStartedBeforeInvalidationDate() | |
| { | |
| $invalidationsToInsert = [ | |
| [ | |
| 'idarchive' => 7, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-01 16:00:00', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, 'ts_started' => '2025-02-05 11:30:00', 'processing_host' => 'host1', 'process_id' => 1256, | |
| ], | |
| [ | |
| 'idarchive' => null, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-03 02:55:55', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, 'ts_started' => '2025-01-01 08:00:00', 'processing_host' => 'host4', 'process_id' => 22555, | |
| ], | |
| ]; | |
| $this->insertInvalidations($invalidationsToInsert); | |
| $inProgressInvalidationCount = $this->getInProgressInvalidationCount(); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '--processing-host' => ['host1'], | |
| '--dry-run' => true, | |
| ]); | |
| $inProgressInvalidationCountAfterDryRun = $this->getInProgressInvalidationCount(); | |
| self::assertEquals($inProgressInvalidationCount, $inProgressInvalidationCountAfterDryRun); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $expectedOutput = '1 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| '; | |
| self::assertStringContainsString($expectedOutput, $this->applicationTester->getDisplay(true)); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '--processing-host' => ['host1'], | |
| '-vvv' => true, | |
| ]); | |
| self::assertEquals(1, $this->getInProgressInvalidationCount()); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $rows = Db::fetchAll('SELECT * FROM ' . Common::prefixTable('archive_invalidations')); | |
| self::assertEquals(2, count($rows)); | |
| self::assertStringNotContainsString('Found duplicate invalidation', $this->getLogOutput()); | |
| } | |
| public function testDuplicateInvalidationIsRemovedWhenBothAreReset() | |
| { | |
| $invalidationsToInsert = [ | |
| [ | |
| 'idarchive' => 7, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-01 16:00:00', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, 'ts_started' => '2025-02-05 11:30:00', 'processing_host' => 'host1', 'process_id' => 1256, | |
| ], | |
| [ | |
| 'idarchive' => null, 'name' => 'done', 'idsite' => 1, 'date1' => '2025-01-01', 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, 'ts_invalidated' => '2025-01-03 02:55:55', 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, 'ts_started' => '2025-01-01 08:00:00', 'processing_host' => 'host4', 'process_id' => 22555, | |
| ], | |
| ]; | |
| $this->insertInvalidations($invalidationsToInsert); | |
| $inProgressInvalidationCount = $this->getInProgressInvalidationCount(); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '--dry-run' => true, | |
| ]); | |
| $inProgressInvalidationCountAfterDryRun = $this->getInProgressInvalidationCount(); | |
| self::assertEquals($inProgressInvalidationCount, $inProgressInvalidationCountAfterDryRun); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $expectedOutput = '2 invalidations found: | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | name | idsite | report | date1 | date2 | period | ts_invalidated | ts_started | processing_host | process_id | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-03 02:55:55 | 2025-01-01 08:00:00 | host4 | 22555 | | |
| | done | 1 | | 2025-01-01 | 2025-01-01 | 1 | 2025-01-01 16:00:00 | 2025-02-05 11:30:00 | host1 | 1256 | | |
| +------+--------+--------+------------+------------+--------+---------------------+---------------------+-----------------+------------+ | |
| '; | |
| self::assertStringContainsString($expectedOutput, $this->applicationTester->getDisplay(true)); | |
| $code = $this->applicationTester->run([ | |
| 'command' => 'core:reset-invalidations', | |
| '-vvv' => true, | |
| ]); | |
| self::assertEquals(0, $this->getInProgressInvalidationCount()); | |
| self::assertEquals(0, $code, $this->getCommandDisplayOutputErrorMessage()); | |
| $rows = Db::fetchAll('SELECT * FROM ' . Common::prefixTable('archive_invalidations')); | |
| self::assertEquals(1, count($rows)); | |
| self::assertStringContainsString('Found duplicate invalidation for params (name = done, idsite = 1, date1 = 2025-01-01, date2 = 2025-01-01, period = 1, report = ). Removing invalidation 2 instead of resetting it.', $this->getLogOutput()); | |
| } | |
| /** | |
| * @return array<string, mixed> | |
| */ | |
| public static function provideContainerConfigBeforeClass(): array | |
| { | |
| if (null === self::$captureHandler) { | |
| self::$captureHandler = new class extends AbstractProcessingHandler { | |
| public $messages = []; | |
| protected function write(array $record) | |
| { | |
| $this->messages[] = (string)$record['formatted']; | |
| } | |
| }; | |
| } | |
| return [ | |
| 'ini.tests.enable_logging' => 1, | |
| 'Tests.log.allowAllHandlers' => true, | |
| 'log.handlers' => [self::$captureHandler], | |
| ]; | |
| } | |
| private function getLogOutput(): string | |
| { | |
| return implode("\n", self::$captureHandler->messages); | |
| } | |
| private function getInProgressInvalidationCount(): int | |
| { | |
| return (int) Db::fetchOne('SELECT COUNT(*) FROM ' . Common::prefixTable('archive_invalidations') . ' WHERE status = 1'); | |
| } | |
| private function prepareInvalidations(): void | |
| { | |
| $invalidationsToInsert = [ | |
| // invalidations idsite 1 | |
| [ | |
| 'idarchive' => 7, | |
| 'name' => 'done', | |
| 'idsite' => 1, | |
| 'date1' => '2025-01-01', | |
| 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, | |
| 'ts_invalidated' => '2025-01-01 16:00:00', | |
| 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, | |
| 'ts_started' => '2025-02-05 11:30:00', | |
| 'processing_host' => 'host1', | |
| 'process_id' => 1256, | |
| ], | |
| [ | |
| 'idarchive' => null, | |
| 'name' => 'done', | |
| 'idsite' => 1, | |
| 'date1' => '2024-12-30', | |
| 'date2' => '2025-01-05', | |
| 'period' => Week::PERIOD_ID, | |
| 'ts_invalidated' => '2025-01-01 16:00:01', | |
| 'status' => ArchiveInvalidator::INVALIDATION_STATUS_QUEUED, | |
| 'report' => null, | |
| 'ts_started' => null, | |
| 'processing_host' => null, | |
| 'process_id' => null, | |
| ], | |
| [ | |
| 'idarchive' => 66, | |
| 'name' => 'donec7445c35d0f9b340f5851df27a15c5ef.Actions', | |
| 'idsite' => 1, | |
| 'date1' => '2025-01-01', | |
| 'date2' => '2025-12-31', | |
| 'period' => Year::PERIOD_ID, | |
| 'ts_invalidated' => '2025-01-01 16:00:02', | |
| 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, | |
| 'ts_started' => '2025-02-05 16:44:22', | |
| 'processing_host' => 'anotherhost', | |
| 'process_id' => 662, | |
| ], | |
| // invalidations idsite 2 | |
| [ | |
| 'idarchive' => 7, | |
| 'name' => 'done', | |
| 'idsite' => 2, | |
| 'date1' => '2025-01-01', | |
| 'date2' => '2025-01-01', | |
| 'period' => Day::PERIOD_ID, | |
| 'ts_invalidated' => '2025-01-01 19:15:00', | |
| 'status' => ArchiveInvalidator::INVALIDATION_STATUS_QUEUED, | |
| 'report' => null, | |
| 'ts_started' => null, | |
| 'processing_host' => null, | |
| 'process_id' => null, | |
| ], | |
| [ | |
| 'idarchive' => null, | |
| 'name' => 'done', | |
| 'idsite' => 2, | |
| 'date1' => '2024-12-30', | |
| 'date2' => '2025-01-05', | |
| 'period' => Week::PERIOD_ID, | |
| 'ts_invalidated' => '2025-01-01 19:15:01', | |
| 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, | |
| 'ts_started' => '2025-02-05 09:11:00', | |
| 'processing_host' => 'host1', | |
| 'process_id' => 2333, | |
| ], | |
| [ | |
| 'idarchive' => 66, | |
| 'name' => 'donec7445c35d0f9b340f5851df27a15c5ef', | |
| 'idsite' => 2, | |
| 'date1' => '2025-01-01', | |
| 'date2' => '2025-12-31', | |
| 'period' => Year::PERIOD_ID, | |
| 'ts_invalidated' => '2025-01-01 19:15:02', | |
| 'status' => ArchiveInvalidator::INVALIDATION_STATUS_QUEUED, | |
| 'report' => null, | |
| 'ts_started' => null, | |
| 'processing_host' => null, | |
| 'process_id' => null, | |
| ], | |
| // invalidations idsite 3 | |
| [ | |
| 'idarchive' => null, | |
| 'name' => 'done.VisitsSummary', | |
| 'idsite' => 3, | |
| 'date1' => '2025-02-01', | |
| 'date2' => '2025-02-28', | |
| 'period' => Month::PERIOD_ID, | |
| 'ts_invalidated' => '2025-02-020 19:15:01', | |
| 'status' => ArchiveInvalidator::INVALIDATION_STATUS_IN_PROGRESS, | |
| 'report' => null, | |
| 'ts_started' => '2025-02-23 18:35:00', | |
| 'processing_host' => 'random', | |
| 'process_id' => 8558, | |
| ], | |
| ]; | |
| $this->insertInvalidations($invalidationsToInsert); | |
| } | |
| private function insertInvalidations(array $invalidationsToInsert): void | |
| { | |
| Db::exec('TRUNCATE TABLE ' . Common::prefixTable('archive_invalidations')); | |
| $sql = 'INSERT INTO ' . Common::prefixTable('archive_invalidations') | |
| . ' (`idarchive`, `name`, `idsite`, `date1`, `date2`, `period`, `ts_invalidated`, `status`, `report`, `ts_started`, `processing_host`, `process_id`)' | |
| . ' VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; | |
| foreach ($invalidationsToInsert as $invalidation) { | |
| Db::query($sql, array_values($invalidation)); | |
| } | |
| } | |
| } | |