/** * tests ProcessFailedException uses information from process output * to generate exception message */ public function testProcessFailedExceptionPopulatesInformationFromProcessOutput() { $cmd = 'php'; $output = "Command output"; $errorOutput = "FATAL: Unexpected error"; $process = $this->getMock('Symfony\\Component\\Process\\Process', array('isSuccessful', 'getOutput', 'getErrorOutput'), array($cmd)); $process->expects($this->once())->method('isSuccessful')->will($this->returnValue(false)); $process->expects($this->once())->method('getOutput')->will($this->returnValue($output)); $process->expects($this->once())->method('getErrorOutput')->will($this->returnValue($errorOutput)); $exception = new ProcessFailedException($process); $this->assertEquals("The command \"{$cmd}\" failed.\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}", $exception->getMessage()); }
public static function verifyNodeVersion() { $process = new Process('node -v'); $process->run(); if (!$process->isSuccessful()) { $exception = new ProcessFailedException($process); throw new \RuntimeException("The npm binary could not be executed successfully. Details:\n" . $exception->getMessage()); } $version = ltrim(trim($process->getOutput()), 'v'); if (!preg_match('{^4\\.}', $version)) { throw new \RuntimeException(sprintf('The required npm version is 4.*.*, found version %s.', $version)); } }
/** * Tests that ProcessFailedException does not extract information from * process output if it was previously disabled */ public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput() { $cmd = 'php'; $exitCode = 1; $exitText = 'General error'; $process = $this->getMock('Symfony\\Component\\Process\\Process', array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput'), array($cmd)); $process->expects($this->once())->method('isSuccessful')->will($this->returnValue(false)); $process->expects($this->never())->method('getOutput'); $process->expects($this->never())->method('getErrorOutput'); $process->expects($this->once())->method('getExitCode')->will($this->returnValue($exitCode)); $process->expects($this->once())->method('getExitCodeText')->will($this->returnValue($exitText)); $process->expects($this->once())->method('isOutputDisabled')->will($this->returnValue(true)); $exception = new ProcessFailedException($process); $this->assertEquals("The command \"{$cmd}\" failed.\nExit Code: {$exitCode}({$exitText})", $exception->getMessage()); }
/** * @param string $command - e.g. clear:cache --no-warmup * @param string $application - console or dist * * @return string * @throws ProcessFailedException */ protected function runCommand($command, $application = 'console') { $phpPath = $this->getPhpExecutablePath(); $command = sprintf('"%s" "%s/%s" %s --env=%s', $phpPath, $this->applicationRootDir, $application, $command, $this->environment); $this->logger->info(sprintf('Executing "%s"', $command)); $process = new Process($command); $process->setWorkingDirectory(realpath($this->applicationRootDir . '/..')); // project root $process->setTimeout(600); $process->run(); if (!$process->isSuccessful()) { $processFailedException = new ProcessFailedException($process); $this->logger->error($processFailedException->getMessage()); throw $processFailedException; } $output = $process->getOutput(); $this->logger->info($output); return $output; }
/** * Cleans up stale jobs. * * A stale job is a job where this command has exited with an error * condition. Although this command is very robust, there might be cases * where it might be terminated abruptly (like a PHP segfault, a SIGTERM signal, etc.). * * In such an error condition, these jobs are cleaned-up on restart of this command. */ private function cleanUpStaleJobs($workerName) { /** @var Job[] $staleJobs */ $staleJobs = $this->getEntityManager()->createQuery("SELECT j FROM " . Job::class . " j WHERE j.state = :running AND (j.workerName = :worker OR j.workerName IS NULL)")->setParameter('worker', $workerName)->setParameter('running', Job::STATE_RUNNING)->getResult(); foreach ($staleJobs as $job) { // If the original job has retry jobs, then one of them is still in // running state. We can skip the original job here as it will be // processed automatically once the retry job is processed. if (!$job->isRetryJob() && count($job->getRetryJobs()) > 0) { continue; } $pb = $this->getCommandProcessBuilder(); $pb->add('jms-job-queue:mark-incomplete')->add($job->getId())->add('--env=' . $this->env)->add('--verbose'); // We use a separate process to clean up. $proc = $pb->getProcess(); if (0 !== $proc->run()) { $ex = new ProcessFailedException($proc); $this->output->writeln(sprintf('There was an error when marking %s as incomplete: %s', $job, $ex->getMessage())); } } }
/** * Tests that ProcessFailedException does not extract information from * process output if it was previously disabled. */ public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput() { $cmd = 'php'; $exitCode = 1; $exitText = 'General error'; $workingDirectory = getcwd(); $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock(); $process->expects($this->once()) ->method('isSuccessful') ->will($this->returnValue(false)); $process->expects($this->never()) ->method('getOutput'); $process->expects($this->never()) ->method('getErrorOutput'); $process->expects($this->once()) ->method('getExitCode') ->will($this->returnValue($exitCode)); $process->expects($this->once()) ->method('getExitCodeText') ->will($this->returnValue($exitText)); $process->expects($this->once()) ->method('isOutputDisabled') ->will($this->returnValue(true)); $process->expects($this->once()) ->method('getWorkingDirectory') ->will($this->returnValue($workingDirectory)); $exception = new ProcessFailedException($process); $this->assertEquals( "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}", $exception->getMessage() ); }
/** * Cleans up stale jobs. * * A stale job is a job where this command has exited with an error * condition. Although this command is very robust, there might be cases * where it might be terminated abruptly (like a PHP segfault, a SIGTERM signal, etc.). * * In such an error condition, these jobs are cleaned-up on restart of this command. */ private function cleanUpStaleJobs() { $repo = $this->getRepository(); foreach ($repo->findBy(array('state' => Job::STATE_RUNNING)) as $job) { // If the original job has retry jobs, then one of them is still in // running state. We can skip the original job here as it will be // processed automatically once the retry job is processed. if (!$job->isRetryJob() && count($job->getRetryJobs()) > 0) { continue; } $pb = $this->getCommandProcessBuilder(); $pb->add('jms-job-queue:mark-incomplete')->add($job->getId())->add('--env=' . $this->env)->add('--verbose'); // We use a separate process to clean up. $proc = $pb->getProcess(); if (0 !== $proc->run()) { $ex = new ProcessFailedException($proc); $this->output->writeln(sprintf('There was an error when marking %s as incomplete: %s', $job, $ex->getMessage())); } } }
/** * ProcessFailedException constructor. * * @param Symfony_ProcessFailedException $previous */ public function __construct(Symfony_ProcessFailedException $previous) { $message = "LVM-data-fetching script exited with a non-zero exit " . "status :( - " . $previous->getMessage(); parent::__construct($message, 0, $previous); }