diff --git a/Command/CachePoolPruneCommand.php b/Command/CachePoolPruneCommand.php index 745a001cc..a7c8ba121 100644 --- a/Command/CachePoolPruneCommand.php +++ b/Command/CachePoolPruneCommand.php @@ -50,14 +50,21 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); + $exitCode = Command::SUCCESS; foreach ($this->pools as $name => $pool) { $io->comment(\sprintf('Pruning cache pool: %s', $name)); - $pool->prune(); + + if (!$pool->prune()) { + $io->error(\sprintf('Cache pool "%s" could not be pruned.', $name)); + $exitCode = Command::FAILURE; + } } - $io->success('Successfully pruned cache pool(s).'); + if (Command::SUCCESS === $exitCode) { + $io->success('Successfully pruned cache pool(s).'); + } - return 0; + return $exitCode; } } diff --git a/Tests/Command/CachePruneCommandTest.php b/Tests/Command/CachePruneCommandTest.php index a2d0ad7fe..580a9f5c1 100644 --- a/Tests/Command/CachePruneCommandTest.php +++ b/Tests/Command/CachePruneCommandTest.php @@ -35,6 +35,44 @@ public function testCommandWithNoPools() $tester->execute([]); } + public function testCommandFailsOnPruneError() + { + $failedPool = $this->createMock(PruneableInterface::class); + $failedPool->expects($this->once())->method('prune')->willReturn(false); + + $generator = new RewindableGenerator(static function () use ($failedPool) { + yield 'failed_pool' => $failedPool; + }, 1); + + $tester = $this->getCommandTester($this->getKernel(), $generator); + $tester->execute([]); + + $this->assertSame(1, $tester->getStatusCode()); + $this->assertStringContainsString('[ERROR] Cache pool "failed_pool" could not be pruned.', $tester->getDisplay()); + } + + public function testCommandContinuesOnFailure() + { + $failedPool = $this->createMock(PruneableInterface::class); + $failedPool->expects($this->once())->method('prune')->willReturn(false); + + $successPool = $this->createMock(PruneableInterface::class); + $successPool->expects($this->once())->method('prune')->willReturn(true); + + $generator = new RewindableGenerator(static function () use ($failedPool, $successPool) { + yield 'failed_pool' => $failedPool; + yield 'success_pool' => $successPool; + }, 2); + + $tester = $this->getCommandTester($this->getKernel(), $generator); + $tester->execute([]); + + $this->assertSame(1, $tester->getStatusCode()); + $display = $tester->getDisplay(); + $this->assertStringContainsString('[ERROR] Cache pool "failed_pool" could not be pruned.', $display); + $this->assertStringContainsString('Pruning cache pool: success_pool', $display); + } + private function getRewindableGenerator(): RewindableGenerator { return new RewindableGenerator(function () { @@ -45,7 +83,7 @@ private function getRewindableGenerator(): RewindableGenerator private function getEmptyRewindableGenerator(): RewindableGenerator { - return new RewindableGenerator(fn () => new \ArrayIterator([]), 0); + return new RewindableGenerator(static fn () => new \ArrayIterator([]), 0); } private function getKernel(): MockObject&KernelInterface