From 76018557987deaaf732255822cf4b5dcbbe80352 Mon Sep 17 00:00:00 2001 From: Nikolas Evers Date: Wed, 7 Oct 2026 11:33:53 +0200 Subject: [PATCH] fix: flush migration logs after each process message --- src/DependencyInjection/migration.php | 1 + .../Handler/MigrationProcessHandler.php | 3 + .../Handler/MigrationProcessHandlerTest.php | 73 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/src/DependencyInjection/migration.php b/src/DependencyInjection/migration.php index 8e2ca1214..4230c1cbf 100644 --- a/src/DependencyInjection/migration.php +++ b/src/DependencyInjection/migration.php @@ -429,6 +429,7 @@ service(MigrationContextFactory::class), service(MigrationProcessorRegistry::class), service(MigrationConfiguration::class), + service(LoggingService::class), ]) ->tag('messenger.message_handler'); diff --git a/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php b/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php index 9b0793b38..62ab05de8 100644 --- a/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php +++ b/src/Migration/MessageQueue/Handler/MigrationProcessHandler.php @@ -12,6 +12,7 @@ use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\Log\Package; use SwagMigrationAssistant\Exception\MigrationException; +use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\MessageQueue\Message\MigrationProcessMessage; use SwagMigrationAssistant\Migration\MigrationConfiguration; use SwagMigrationAssistant\Migration\MigrationContextFactoryInterface; @@ -34,6 +35,7 @@ public function __construct( private readonly MigrationContextFactoryInterface $migrationContextFactory, private readonly MigrationProcessorRegistry $processorRegistry, private readonly MigrationConfiguration $migrationConfig, + private readonly LoggingServiceInterface $loggingService, ) { } @@ -60,6 +62,7 @@ public function __invoke(MigrationProcessMessage $message): void $processor = $this->processorRegistry->getProcessor($run->getStep()); $processor?->process($migrationContext, $context, $run, $progress); + $this->loggingService->flush(); } private function getCurrentRun(MigrationProcessMessage $message, Context $context): SwagMigrationRunEntity diff --git a/tests/Migration/MessageQueue/Handler/MigrationProcessHandlerTest.php b/tests/Migration/MessageQueue/Handler/MigrationProcessHandlerTest.php index 6f377495d..20fc40779 100644 --- a/tests/Migration/MessageQueue/Handler/MigrationProcessHandlerTest.php +++ b/tests/Migration/MessageQueue/Handler/MigrationProcessHandlerTest.php @@ -8,15 +8,22 @@ namespace SwagMigrationAssistant\Test\Migration\MessageQueue\Handler; use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; use Shopware\Core\Framework\Context; use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection; use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository; +use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent; use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria; use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult; +use Shopware\Core\Framework\Event\NestedEventCollection; use Shopware\Core\Framework\Log\Package; use Shopware\Core\Framework\Uuid\Uuid; use SwagMigrationAssistant\Exception\MigrationException; use SwagMigrationAssistant\Migration\Connection\SwagMigrationConnectionEntity; +use SwagMigrationAssistant\Migration\Logging\Log\Builder\MigrationLogBuilder; +use SwagMigrationAssistant\Migration\Logging\Log\MediaFileMissingLog; +use SwagMigrationAssistant\Migration\Logging\LoggingService; +use SwagMigrationAssistant\Migration\Logging\LoggingServiceInterface; use SwagMigrationAssistant\Migration\MessageQueue\Handler\MigrationProcessHandler; use SwagMigrationAssistant\Migration\MessageQueue\Handler\MigrationProcessorRegistry; use SwagMigrationAssistant\Migration\MessageQueue\Handler\Processor\MigrationProcessorInterface; @@ -43,6 +50,7 @@ protected function setUp(): void $this->createMock(MigrationContextFactoryInterface::class), $this->createMock(MigrationProcessorRegistry::class), new MigrationConfiguration(), + $this->createMock(LoggingServiceInterface::class), ); } @@ -79,6 +87,7 @@ public function testInvokeWithoutRunProgress(): void $this->createMock(MigrationContextFactoryInterface::class), $this->createMock(MigrationProcessorRegistry::class), new MigrationConfiguration(), + $this->createMock(LoggingServiceInterface::class), ); $message = new MigrationProcessMessage(Context::createDefaultContext(), Uuid::randomHex()); @@ -113,6 +122,7 @@ public function testInvokeWithoutMigrationContext(): void $this->createMock(MigrationContextFactoryInterface::class), $this->createMock(MigrationProcessorRegistry::class), new MigrationConfiguration(), + $this->createMock(LoggingServiceInterface::class), ); $message = new MigrationProcessMessage(Context::createDefaultContext(), Uuid::randomHex()); @@ -160,10 +170,73 @@ public function testInvoke(): void $migrationContextFactory, $processorRegistry, new MigrationConfiguration(), + $this->createMock(LoggingServiceInterface::class), ); $message = new MigrationProcessMessage(Context::createDefaultContext(), Uuid::randomHex()); $this->migrationProcessHandler->__invoke($message); } + + public function testInvokeFlushesLogsOfTheProcessedStep(): void + { + $writtenLogs = 0; + $loggingRepo = $this->createMock(EntityRepository::class); + $loggingRepo->method('create')->willReturnCallback( + static function (array $logs) use (&$writtenLogs): EntityWrittenContainerEvent { + $writtenLogs += \count($logs); + + return new EntityWrittenContainerEvent(Context::createDefaultContext(), new NestedEventCollection(), []); + } + ); + $loggingService = new LoggingService($loggingRepo, new NullLogger(), new MigrationConfiguration()); + + $run = new SwagMigrationRunEntity(); + $run->setId(Uuid::randomHex()); + $run->setProgress(new MigrationProgress(0, 100, new ProgressDataSetCollection(), 'media', 0)); + $run->setStep(MigrationStep::MEDIA_PROCESSING); + + $repository = $this->createMock(EntityRepository::class); + $repository->method('search')->willReturn( + new EntitySearchResult( + SwagMigrationRunDefinition::ENTITY_NAME, + 1, + new EntityCollection([$run]), + null, + new Criteria(), + Context::createDefaultContext() + ) + ); + + $processor = $this->createMock(MigrationProcessorInterface::class); + $processor->method('process')->willReturnCallback( + static function () use ($loggingService, $run): void { + $loggingService->log( + (new MigrationLogBuilder($run->getId(), Shopware55Profile::PROFILE_NAME, 'local')) + ->build(MediaFileMissingLog::class) + ); + } + ); + + $processorRegistry = $this->createMock(MigrationProcessorRegistry::class); + $processorRegistry->method('getProcessor')->willReturn($processor); + + $migrationContextFactory = $this->createMock(MigrationContextFactoryInterface::class); + $migrationContextFactory->method('create')->willReturn(new MigrationContext( + new SwagMigrationConnectionEntity(), + new Shopware55Profile() + )); + + $handler = new MigrationProcessHandler( + $repository, + $migrationContextFactory, + $processorRegistry, + new MigrationConfiguration(), + $loggingService, + ); + + $handler->__invoke(new MigrationProcessMessage(Context::createDefaultContext(), Uuid::randomHex())); + + static::assertSame(1, $writtenLogs); + } }