Răsfoiți Sursa

Created ProcessRunnerTest

Alejandro Celaya 3 ani în urmă
părinte
comite
4e00c950cc

+ 1 - 0
CHANGELOG.md

@@ -28,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
 ### Changed
 * [#977](https://github.com/shlinkio/shlink/issues/977) Migrated from `laminas/laminas-paginator` to `pagerfanta/core` to handle pagination.
 * [#986](https://github.com/shlinkio/shlink/issues/986) Updated official docker image to use PHP 8.
+* [#1010](https://github.com/shlinkio/shlink/issues/1010) Increased timeout for database commands to 10 minutes.
 
 ### Deprecated
 * [#959](https://github.com/shlinkio/shlink/issues/959) Deprecated all command flags using camelCase format (like `--expirationDate`), adding kebab-case replacements for all of them (like `--expiration-date`).

+ 8 - 2
module/CLI/src/Util/ProcessRunner.php

@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Shlinkio\Shlink\CLI\Util;
 
+use Closure;
 use Shlinkio\Shlink\CLI\Command\Util\LockedCommandConfig;
 use Symfony\Component\Console\Helper\DebugFormatterHelper;
 use Symfony\Component\Console\Helper\ProcessHelper;
@@ -18,10 +19,14 @@ use function str_replace;
 class ProcessRunner implements ProcessRunnerInterface
 {
     private ProcessHelper $helper;
+    private Closure $createProcess;
 
-    public function __construct(ProcessHelper $helper)
+    public function __construct(ProcessHelper $helper, ?callable $createProcess = null)
     {
         $this->helper = $helper;
+        $this->createProcess = $createProcess !== null
+            ? Closure::fromCallable($createProcess)
+            : static fn (array $cmd) => new Process($cmd, null, null, null, LockedCommandConfig::DEFAULT_TTL);
     }
 
     public function run(OutputInterface $output, array $cmd): void
@@ -32,7 +37,8 @@ class ProcessRunner implements ProcessRunnerInterface
 
         /** @var DebugFormatterHelper $formatter */
         $formatter = $this->helper->getHelperSet()->get('debug_formatter');
-        $process = new Process($cmd, null, null, null, LockedCommandConfig::DEFAULT_TTL);
+        /** @var Process $process */
+        $process = ($this->createProcess)($cmd);
 
         if ($output->isVeryVerbose()) {
             $output->write(

+ 106 - 0
module/CLI/test/Util/ProcessRunnerTest.php

@@ -0,0 +1,106 @@
+<?php
+
+declare(strict_types=1);
+
+namespace ShlinkioTest\Shlink\CLI\Util;
+
+use PHPUnit\Framework\TestCase;
+use Prophecy\Argument;
+use Prophecy\PhpUnit\ProphecyTrait;
+use Prophecy\Prophecy\ObjectProphecy;
+use Shlinkio\Shlink\CLI\Util\ProcessRunner;
+use Symfony\Component\Console\Helper\DebugFormatterHelper;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Helper\ProcessHelper;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Process\Process;
+
+class ProcessRunnerTest extends TestCase
+{
+    use ProphecyTrait;
+
+    private ProcessRunner $runner;
+    private ObjectProphecy $helper;
+    private ObjectProphecy $formatter;
+    private ObjectProphecy $process;
+    private ObjectProphecy $output;
+
+    protected function setUp(): void
+    {
+        $this->helper = $this->prophesize(ProcessHelper::class);
+        $this->formatter = $this->prophesize(DebugFormatterHelper::class);
+        $helperSet = $this->prophesize(HelperSet::class);
+        $helperSet->get('debug_formatter')->willReturn($this->formatter->reveal());
+        $this->helper->getHelperSet()->willReturn($helperSet->reveal());
+        $this->process = $this->prophesize(Process::class);
+
+        $this->runner = new ProcessRunner($this->helper->reveal(), fn () => $this->process->reveal());
+        $this->output = $this->prophesize(OutputInterface::class);
+    }
+
+    /** @test */
+    public function noMessagesAreWrittenWhenOutputIsNotVerbose(): void
+    {
+        $isVeryVerbose = $this->output->isVeryVerbose()->willReturn(false);
+        $isDebug = $this->output->isDebug()->willReturn(false);
+        $mustRun = $this->process->mustRun(Argument::cetera())->willReturn($this->process->reveal());
+
+        $this->runner->run($this->output->reveal(), []);
+
+        $isVeryVerbose->shouldHaveBeenCalledTimes(2);
+        $isDebug->shouldHaveBeenCalledOnce();
+        $mustRun->shouldHaveBeenCalledOnce();
+        $this->process->isSuccessful()->shouldNotHaveBeenCalled();
+        $this->process->getCommandLine()->shouldNotHaveBeenCalled();
+        $this->output->write(Argument::cetera())->shouldNotHaveBeenCalled();
+        $this->helper->wrapCallback(Argument::cetera())->shouldNotHaveBeenCalled();
+        $this->formatter->start(Argument::cetera())->shouldNotHaveBeenCalled();
+        $this->formatter->stop(Argument::cetera())->shouldNotHaveBeenCalled();
+    }
+
+    /** @test */
+    public function someMessagesAreWrittenWhenOutputIsVerbose(): void
+    {
+        $isVeryVerbose = $this->output->isVeryVerbose()->willReturn(true);
+        $isDebug = $this->output->isDebug()->willReturn(false);
+        $mustRun = $this->process->mustRun(Argument::cetera())->willReturn($this->process->reveal());
+        $isSuccessful = $this->process->isSuccessful()->willReturn(true);
+        $getCommandLine = $this->process->getCommandLine()->willReturn('true');
+        $start = $this->formatter->start(Argument::cetera())->willReturn('');
+        $stop = $this->formatter->stop(Argument::cetera())->willReturn('');
+
+        $this->runner->run($this->output->reveal(), []);
+
+        $isVeryVerbose->shouldHaveBeenCalledTimes(2);
+        $isDebug->shouldHaveBeenCalledOnce();
+        $mustRun->shouldHaveBeenCalledOnce();
+        $this->output->write(Argument::cetera())->shouldHaveBeenCalledTimes(2);
+        $this->helper->wrapCallback(Argument::cetera())->shouldNotHaveBeenCalled();
+        $isSuccessful->shouldHaveBeenCalledTimes(2);
+        $getCommandLine->shouldHaveBeenCalledOnce();
+        $start->shouldHaveBeenCalledOnce();
+        $stop->shouldHaveBeenCalledOnce();
+    }
+
+    /** @test */
+    public function wrapsCallbackWhenOutputIsDebug(): void
+    {
+        $isVeryVerbose = $this->output->isVeryVerbose()->willReturn(false);
+        $isDebug = $this->output->isDebug()->willReturn(true);
+        $mustRun = $this->process->mustRun(Argument::cetera())->willReturn($this->process->reveal());
+        $wrapCallback = $this->helper->wrapCallback(Argument::cetera())->willReturn(function (): void {
+        });
+
+        $this->runner->run($this->output->reveal(), []);
+
+        $isVeryVerbose->shouldHaveBeenCalledTimes(2);
+        $isDebug->shouldHaveBeenCalledOnce();
+        $mustRun->shouldHaveBeenCalledOnce();
+        $wrapCallback->shouldHaveBeenCalledOnce();
+        $this->process->isSuccessful()->shouldNotHaveBeenCalled();
+        $this->process->getCommandLine()->shouldNotHaveBeenCalled();
+        $this->output->write(Argument::cetera())->shouldNotHaveBeenCalled();
+        $this->formatter->start(Argument::cetera())->shouldNotHaveBeenCalled();
+        $this->formatter->stop(Argument::cetera())->shouldNotHaveBeenCalled();
+    }
+}