diff --git a/.travis.yml b/.travis.yml index 8f0e13a792..a783a64e6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,7 @@ addons: cache: directories: - .phpunit + - php-5.3.9 matrix: include: @@ -32,6 +33,7 @@ env: before_install: - if [[ "$deps" = "no" ]] && [[ "$TRAVIS_PHP_VERSION" =~ 5.[45] ]] && [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then export deps=skip; fi; + - if [[ $deps = no && $TRAVIS_PHP_VERSION = 5.3 && ! -d php-5.3.9/sapi ]]; then wget http://museum.php.net/php5/php-5.3.9.tar.bz2; tar -xjf php-5.3.9.tar.bz2; (cd php-5.3.9; ./configure --enable-sigchild --enable-pcntl; make -j2); fi; - if [[ "$TRAVIS_PHP_VERSION" != "hhvm" ]]; then INI_FILE=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; else INI_FILE=/etc/hhvm/php.ini; fi; - echo "memory_limit = -1" >> $INI_FILE - echo "session.gc_probability = 0" >> $INI_FILE @@ -56,6 +58,7 @@ install: script: - if [ "$deps" = "no" ]; then echo "$COMPONENTS" | parallel --gnu '$PHPUNIT --exclude-group tty,benchmark,intl-data {}'; fi; - if [ "$deps" = "no" ]; then echo -e "\\nRunning tests requiring tty"; $PHPUNIT --group tty; fi; + - if [[ $deps = no && $TRAVIS_PHP_VERSION = 5.3 ]]; then echo -e "1\\n0" | parallel --gnu 'echo -e "\\nPHP --enable-sigchild enhanced={}" && ENHANCE_SIGCHLD={} php-5.3.9/sapi/cli/php .phpunit/phpunit-4.8/phpunit --colors=always src/Symfony/Component/Process/'; fi; - if [ "$deps" = "high" ]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer --prefer-source update; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi; - if [ "$deps" = "low" ]; then echo "$COMPONENTS" | parallel --gnu -j10% 'cd {}; composer --prefer-source --prefer-lowest --prefer-stable update; $PHPUNIT --exclude-group tty,benchmark,intl-data'; fi; - if [ "$deps" = "skip" ]; then echo 'This matrix line is skipped for pull requests.'; fi; diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php index 6e85702cf6..f58d4014b6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php @@ -54,7 +54,9 @@ EOF protected function execute(InputInterface $input, OutputInterface $output) { $realCacheDir = $this->getContainer()->getParameter('kernel.cache_dir'); - $oldCacheDir = $realCacheDir.'_old'; + // the old cache dir name must not be longer than the real one to avoid exceeding + // the maximum length of a directory or file path within it (esp. Windows MAX_PATH) + $oldCacheDir = substr($realCacheDir, 0, -1).('~' === substr($realCacheDir, -1) ? '+' : '~'); $filesystem = $this->getContainer()->get('filesystem'); if (!is_writable($realCacheDir)) { @@ -75,7 +77,7 @@ EOF // the warmup cache dir name must have the same length than the real one // to avoid the many problems in serialized resources files $realCacheDir = realpath($realCacheDir); - $warmupDir = substr($realCacheDir, 0, -1).'_'; + $warmupDir = substr($realCacheDir, 0, -1).('_' === substr($realCacheDir, -1) ? '-' : '_'); if ($filesystem->exists($warmupDir)) { if ($output->isVerbose()) { @@ -114,8 +116,6 @@ EOF */ protected function warmup($warmupDir, $realCacheDir, $enableOptionalWarmers = true) { - $this->getContainer()->get('filesystem')->remove($warmupDir); - // create a temporary kernel $realKernel = $this->getContainer()->get('kernel'); $realKernelClass = get_class($realKernel); diff --git a/src/Symfony/Component/Process/Process.php b/src/Symfony/Component/Process/Process.php index 5cfcf8b8b5..aa9a8c31ad 100644 --- a/src/Symfony/Component/Process/Process.php +++ b/src/Symfony/Component/Process/Process.php @@ -54,7 +54,7 @@ class Process private $idleTimeout; private $options; private $exitcode; - private $fallbackExitcode; + private $fallbackStatus = array(); private $processInformation; private $outputDisabled = false; private $stdout; @@ -75,6 +75,14 @@ class Process private $latestSignal; private static $sigchild; + private static $posixSignals = array( + 1 => 1, // SIGHUP + 2 => 2, // SIGINT + 3 => 3, // SIGQUIT + 6 => 6, // SIGABRT + 14 => 14, // SIGALRM + 15 => 15, // SIGTERM + ); /** * Exit codes translation table. @@ -169,16 +177,7 @@ class Process public function __destruct() { - if ($this->isRunning()) { - $this->doSignal(15, false); - usleep(10000); - } - if ($this->isRunning()) { - usleep(100000); - $this->doSignal(9, false); - } - - // Don't call ->stop() nor ->close() since we don't want to wait for the subprocess here + $this->stop(0); } public function __clone() @@ -227,7 +226,7 @@ class Process */ public function mustRun($callback = null) { - if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { + if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); } @@ -388,17 +387,9 @@ class Process * Returns the Pid (process identifier), if applicable. * * @return int|null The process id if running, null otherwise - * - * @throws RuntimeException In case --enable-sigchild is activated */ public function getPid() { - if ($this->isSigchildEnabled()) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved.'); - } - - $this->updateStatus(false); - return $this->isRunning() ? $this->processInformation['pid'] : null; } @@ -410,7 +401,7 @@ class Process * @return Process * * @throws LogicException In case the process is not running - * @throws RuntimeException In case --enable-sigchild is activated + * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed * @throws RuntimeException In case of failure */ public function signal($signal) @@ -604,7 +595,9 @@ class Process */ public function getExitCode() { - if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) { + if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { + $this->stop(0); + throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'); } @@ -621,8 +614,6 @@ class Process * * @return null|string A string representation for the exit status code, null if the Process is not terminated. * - * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled - * * @see http://tldp.org/LDP/abs/html/exitcodes.html * @see http://en.wikipedia.org/wiki/Unix_signal */ @@ -659,12 +650,12 @@ class Process { $this->requireProcessIsTerminated(__FUNCTION__); - if ($this->isSigchildEnabled()) { + if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { + $this->stop(0); + throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); } - $this->updateStatus(false); - return $this->processInformation['signaled']; } @@ -682,12 +673,12 @@ class Process { $this->requireProcessIsTerminated(__FUNCTION__); - if ($this->isSigchildEnabled()) { + if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 === $this->processInformation['termsig'])) { + $this->stop(0); + throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.'); } - $this->updateStatus(false); - return $this->processInformation['termsig']; } @@ -704,8 +695,6 @@ class Process { $this->requireProcessIsTerminated(__FUNCTION__); - $this->updateStatus(false); - return $this->processInformation['stopped']; } @@ -722,8 +711,6 @@ class Process { $this->requireProcessIsTerminated(__FUNCTION__); - $this->updateStatus(false); - return $this->processInformation['stopsig']; } @@ -797,7 +784,7 @@ class Process usleep(1000); } while ($this->isRunning() && microtime(true) < $timeoutMicro); - if ($this->isRunning() && !$this->isSigchildEnabled()) { + if ($this->isRunning()) { // Avoid exception here: process is supposed to be running, but it might have stopped just // after this line. In any case, let's silently discard the error, we cannot do anything. $this->doSignal($signal ?: 9, false); @@ -1262,9 +1249,15 @@ class Process if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { // last exit code is output on the fourth pipe and caught to work around --enable-sigchild - $descriptors = array_merge($descriptors, array(array('pipe', 'w'))); + $descriptors[3] = array('pipe', 'w'); - $this->commandline = '('.$this->commandline.') 3>/dev/null; code=$?; echo $code >&3; exit $code'; + $trap = ''; + foreach (self::$posixSignals as $s) { + $trap .= "trap 'echo s$s >&3' $s;"; + } + + $this->commandline = $trap.'{ ('.$this->commandline.') <&3 3<&- 3>/dev/null & } 3<&0;'; + $this->commandline .= 'pid=$!; echo p$pid >&3; wait $pid; code=$?; echo x$code >&3; exit $code'; } return $descriptors; @@ -1311,10 +1304,13 @@ class Process } $this->processInformation = proc_get_status($this->process); - $this->captureExitCode(); $this->readPipes($blocking, '\\' === DIRECTORY_SEPARATOR ? !$this->processInformation['running'] : true); + if ($this->fallbackStatus && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { + $this->processInformation = $this->fallbackStatus + $this->processInformation; + } + if (!$this->processInformation['running']) { $this->close(); } @@ -1331,7 +1327,7 @@ class Process return self::$sigchild; } - if (!function_exists('phpinfo')) { + if (!function_exists('phpinfo') || defined('HHVM_VERSION')) { return self::$sigchild = false; } @@ -1375,24 +1371,24 @@ class Process $callback = $this->callback; foreach ($result as $type => $data) { - if (3 == $type) { - $this->fallbackExitcode = (int) $data; + if (3 === $type) { + foreach (explode("\n", substr($data, 0, -1)) as $data) { + if ('p' === $data[0]) { + $this->fallbackStatus['pid'] = (int) substr($data, 1); + } elseif ('s' === $data[0]) { + $this->fallbackStatus['signaled'] = true; + $this->fallbackStatus['exitcode'] = -1; + $this->fallbackStatus['termsig'] = (int) substr($data, 1); + } elseif ('x' === $data[0] && !isset($this->fallbackStatus['signaled'])) { + $this->fallbackStatus['exitcode'] = (int) substr($data, 1); + } + } } else { $callback($type === self::STDOUT ? self::OUT : self::ERR, $data); } } } - /** - * Captures the exitcode if mentioned in the process information. - */ - private function captureExitCode() - { - if (isset($this->processInformation['exitcode']) && -1 != $this->processInformation['exitcode']) { - $this->exitcode = $this->processInformation['exitcode']; - } - } - /** * Closes process resource, closes file handles, sets the exitcode. * @@ -1402,19 +1398,19 @@ class Process { $this->processPipes->close(); if (is_resource($this->process)) { - $exitcode = proc_close($this->process); - } else { - $exitcode = -1; + proc_close($this->process); } - - $this->exitcode = -1 !== $exitcode ? $exitcode : (null !== $this->exitcode ? $this->exitcode : -1); + $this->exitcode = $this->processInformation['exitcode']; $this->status = self::STATUS_TERMINATED; - if (-1 === $this->exitcode && null !== $this->fallbackExitcode) { - $this->exitcode = $this->fallbackExitcode; - } elseif (-1 === $this->exitcode && $this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) { - // if process has been signaled, no exitcode but a valid termsig, apply Unix convention - $this->exitcode = 128 + $this->processInformation['termsig']; + if (-1 === $this->exitcode) { + if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) { + // if process has been signaled, no exitcode but a valid termsig, apply Unix convention + $this->exitcode = 128 + $this->processInformation['termsig']; + } elseif ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) { + $this->processInformation['signaled'] = true; + $this->processInformation['termsig'] = -1; + } } // Free memory from self-reference callback created by buildCallback @@ -1433,7 +1429,7 @@ class Process $this->starttime = null; $this->callback = null; $this->exitcode = null; - $this->fallbackExitcode = null; + $this->fallbackStatus = array(); $this->processInformation = null; $this->stdout = null; $this->stderr = null; @@ -1453,7 +1449,7 @@ class Process * @return bool True if the signal was sent successfully, false otherwise * * @throws LogicException In case the process is not running - * @throws RuntimeException In case --enable-sigchild is activated + * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed * @throws RuntimeException In case of failure */ private function doSignal($signal, $throwException) @@ -1466,9 +1462,9 @@ class Process return false; } - if ($this->isSigchildEnabled()) { + if ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled() && !isset(self::$posixSignals[$signal]) && !(function_exists('posix_kill') && @posix_kill($this->getPid(), $signal))) { if ($throwException) { - throw new RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); + throw new RuntimeException('This PHP has been compiled with --enable-sigchild and posix_kill() is not available.'); } return false; @@ -1493,7 +1489,10 @@ class Process return false; } - $this->latestSignal = $signal; + $this->latestSignal = (int) $signal; + $this->fallbackStatus['signaled'] = true; + $this->fallbackStatus['exitcode'] = -1; + $this->fallbackStatus['termsig'] = $this->latestSignal; return true; } diff --git a/src/Symfony/Component/Process/Tests/PhpProcessTest.php b/src/Symfony/Component/Process/Tests/PhpProcessTest.php index 2cf79aa1a6..9c0f04d3d2 100644 --- a/src/Symfony/Component/Process/Tests/PhpProcessTest.php +++ b/src/Symfony/Component/Process/Tests/PhpProcessTest.php @@ -30,24 +30,20 @@ PHP public function testCommandLine() { - if ('phpdbg' === PHP_SAPI) { - $this->markTestSkipped('phpdbg SAPI is not supported by this test.'); - } - $process = new PhpProcess(<<find(); + $commandLine = $process->getCommandLine(); - $this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP before start'); + $f = new PhpExecutableFinder(); + $this->assertContains($f->find(), $commandLine, '::getCommandLine() returns the command line of PHP before start'); $process->start(); - $this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start'); + $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start'); $process->wait(); - $this->assertSame($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait'); + $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait'); } } diff --git a/src/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php b/src/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php deleted file mode 100644 index 3977bcdcf1..0000000000 --- a/src/Symfony/Component/Process/Tests/ProcessInSigchildEnvironment.php +++ /dev/null @@ -1,22 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\Process; - -class ProcessInSigchildEnvironment extends Process -{ - protected function isSigchildEnabled() - { - return true; - } -} diff --git a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php b/src/Symfony/Component/Process/Tests/ProcessTest.php similarity index 87% rename from src/Symfony/Component/Process/Tests/AbstractProcessTest.php rename to src/Symfony/Component/Process/Tests/ProcessTest.php index 8562b0ce34..7547ba937f 100644 --- a/src/Symfony/Component/Process/Tests/AbstractProcessTest.php +++ b/src/Symfony/Component/Process/Tests/ProcessTest.php @@ -21,9 +21,10 @@ use Symfony\Component\Process\Process; /** * @author Robert Schönthal */ -abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase +class ProcessTest extends \PHPUnit_Framework_TestCase { - protected static $phpBin; + private static $phpBin; + private static $notEnhancedSigchild = false; public static function setUpBeforeClass() { @@ -72,12 +73,11 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertNull($p->getTimeout()); } + /** + * @requires extension pcntl + */ public function testStopWithTimeoutIsActuallyWorking() { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } - // exec is mandatory here since we send a signal to the process // see https://github.com/symfony/symfony/issues/5030 about prepending // command with exec @@ -126,7 +126,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase { $data = ''; - $process = $this->getProcess('echo foo && php -r "sleep(1);" && echo foo'); + $process = $this->getProcess('echo foo && '.self::$phpBin.' -r "sleep(1);" && echo foo'); $process->start(function ($type, $buffer) use (&$data) { $data .= $buffer; }); @@ -461,6 +461,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase if ('\\' === DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does not support POSIX exit code'); } + $this->skipIfNotEnhancedSigchild(); // such command run in bash return an exitcode 127 $process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis'); @@ -489,6 +490,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase if ('\\' === DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does have /dev/tty support'); } + $this->skipIfNotEnhancedSigchild(); $process = $this->getProcess('echo "foo" >> /dev/null'); $process->setTty(true); @@ -497,6 +499,10 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertTrue($process->isSuccessful()); } + /** + * @expectedException \Symfony\Component\Process\Exception\RuntimeException + * @expectedExceptionMessage TTY mode is not supported on Windows platform. + */ public function testTTYInWindowsEnvironment() { if ('\\' !== DIRECTORY_SEPARATOR) { @@ -505,12 +511,13 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $process = $this->getProcess('echo "foo" >> /dev/null'); $process->setTty(false); - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'TTY mode is not supported on Windows platform.'); $process->setTty(true); } public function testExitCodeTextIsNullWhenExitCodeIsNull() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(''); $this->assertNull($process->getExitCodeText()); } @@ -531,6 +538,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testMustRun() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess('echo foo'); $this->assertSame($process, $process->mustRun()); @@ -539,6 +548,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testSuccessfulMustRunHasCorrectExitCode() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess('echo foo')->mustRun(); $this->assertEquals(0, $process->getExitCode()); } @@ -548,12 +559,16 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase */ public function testMustRunThrowsException() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess('exit 1'); $process->mustRun(); } public function testExitCodeText() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(''); $r = new \ReflectionObject($process); $p = $r->getProperty('exitcode'); @@ -582,6 +597,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testGetExitCodeIsNullOnStart() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(self::$phpBin.' -r "usleep(200000);"'); $this->assertNull($process->getExitCode()); $process->start(); @@ -592,6 +609,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testGetExitCodeIsNullOnWhenStartingAgain() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(self::$phpBin.' -r "usleep(200000);"'); $process->run(); $this->assertEquals(0, $process->getExitCode()); @@ -603,6 +622,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testGetExitCode() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(self::$phpBin.' -v'); $process->run(); $this->assertSame(0, $process->getExitCode()); @@ -638,6 +659,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testIsSuccessful() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(self::$phpBin.' -v'); $process->run(); $this->assertTrue($process->isSuccessful()); @@ -645,6 +668,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testIsSuccessfulOnlyAfterTerminated() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(self::$phpBin.' -r "sleep(1);"'); $process->start(); @@ -659,6 +684,8 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase public function testIsNotSuccessful() { + $this->skipIfNotEnhancedSigchild(); + $process = $this->getProcess(self::$phpBin.' -r "usleep(500000);throw new \Exception(\'BOUM\');"'); $process->start(); $this->assertTrue($process->isRunning()); @@ -671,6 +698,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase if ('\\' === DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does not support POSIX signals'); } + $this->skipIfNotEnhancedSigchild(); $process = $this->getProcess(self::$phpBin.' -v'); $process->run(); @@ -682,6 +710,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase if ('\\' === DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does not support POSIX signals'); } + $this->skipIfNotEnhancedSigchild(); $process = $this->getProcess(self::$phpBin.' -v'); $process->run(); @@ -693,6 +722,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase if ('\\' === DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does not support POSIX signals'); } + $this->skipIfNotEnhancedSigchild(); $process = $this->getProcess(self::$phpBin.' -v'); $process->run(); @@ -704,6 +734,7 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase if ('\\' === DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does not support POSIX signals'); } + $this->skipIfNotEnhancedSigchild(); $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"'); $process->start(); @@ -716,22 +747,25 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase if ('\\' === DIRECTORY_SEPARATOR) { $this->markTestSkipped('Windows does not support POSIX signals'); } - - // SIGTERM is only defined if pcntl extension is present - $termSignal = defined('SIGTERM') ? SIGTERM : 15; + $this->skipIfNotEnhancedSigchild(); $process = $this->getProcess(self::$phpBin.' -r "sleep(4);"'); $process->start(); $process->stop(); - $this->assertEquals($termSignal, $process->getTermSignal()); + $this->assertEquals(15, $process->getTermSignal()); // SIGTERM } + /** + * @expectedException \Symfony\Component\Process\Exception\RuntimeException + * @expectedExceptionMessage The process has been signaled + */ public function testProcessThrowsExceptionWhenExternallySignaled() { if (!function_exists('posix_kill')) { $this->markTestSkipped('Function posix_kill is required.'); } + $this->skipIfNotEnhancedSigchild(false); $termSignal = defined('SIGKILL') ? SIGKILL : 9; @@ -739,7 +773,6 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $process->start(); posix_kill($process->getPid(), $termSignal); - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'The process has been signaled with signal "9".'); $process->wait(); } @@ -806,26 +839,23 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase */ public function testCheckTimeoutOnStartedProcess() { - $timeout = 0.5; - $precision = 100000; $process = $this->getProcess(self::$phpBin.' -r "sleep(3);"'); - $process->setTimeout($timeout); - $start = microtime(true); + $process->setTimeout(0.5); $process->start(); + $start = microtime(true); try { while ($process->isRunning()) { $process->checkTimeout(); - usleep($precision); + usleep(100000); } $this->fail('A RuntimeException should have been raised'); } catch (RuntimeException $e) { } $duration = microtime(true) - $start; - $this->assertLessThan($timeout + $precision, $duration); - $this->assertFalse($process->isSuccessful()); + $this->assertLessThan(3, $duration); throw $e; } @@ -908,12 +938,11 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertNull($process->getPid()); } + /** + * @requires extension pcntl + */ public function testSignal() { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } - $process = $this->getProcess('exec '.self::$phpBin.' '.__DIR__.'/SignalListener.php'); $process->start(); @@ -926,11 +955,12 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertEquals('Caught SIGUSR1', $process->getOutput()); } + /** + * @requires extension pcntl + */ public function testExitCodeIsAvailableAfterSignal() { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } + $this->skipIfNotEnhancedSigchild(); $process = $this->getProcess('sleep 4'); $process->start(); @@ -948,15 +978,12 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase /** * @expectedException \Symfony\Component\Process\Exception\LogicException + * @expectedExceptionMessage Can not send signal on a non running process. */ public function testSignalProcessNotRunning() { - if (!extension_loaded('pcntl')) { - $this->markTestSkipped('Extension pcntl is required.'); - } - $process = $this->getProcess(self::$phpBin.' -v'); - $process->signal(SIGHUP); + $process->signal(1); // SIGHUP } /** @@ -1048,20 +1075,26 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $this->assertFalse($p->isOutputDisabled()); } + /** + * @expectedException \Symfony\Component\Process\Exception\RuntimeException + * @expectedExceptionMessage Disabling output while the process is running is not possible. + */ public function testDisableOutputWhileRunningThrowsException() { $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); $p->start(); - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Disabling output while the process is running is not possible.'); $p->disableOutput(); } + /** + * @expectedException \Symfony\Component\Process\Exception\RuntimeException + * @expectedExceptionMessage Enabling output while the process is running is not possible. + */ public function testEnableOutputWhileRunningThrowsException() { $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); $p->disableOutput(); $p->start(); - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Enabling output while the process is running is not possible.'); $p->enableOutput(); } @@ -1075,19 +1108,25 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $p->disableOutput(); } + /** + * @expectedException \Symfony\Component\Process\Exception\LogicException + * @expectedExceptionMessage Output can not be disabled while an idle timeout is set. + */ public function testDisableOutputWhileIdleTimeoutIsSet() { $process = $this->getProcess('sleep 3'); $process->setIdleTimeout(1); - $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output can not be disabled while an idle timeout is set.'); $process->disableOutput(); } + /** + * @expectedException \Symfony\Component\Process\Exception\LogicException + * @expectedExceptionMessage timeout can not be set while the output is disabled. + */ public function testSetIdleTimeoutWhileOutputIsDisabled() { $process = $this->getProcess('sleep 3'); $process->disableOutput(); - $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Idle timeout can not be set while the output is disabled.'); $process->setIdleTimeout(1); } @@ -1106,6 +1145,9 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); $p->disableOutput(); $this->setExpectedException($exception, $exceptionMessage); + if ('mustRun' === $startMethod) { + $this->skipIfNotEnhancedSigchild(); + } $p->{$startMethod}(function () {}); } @@ -1120,13 +1162,14 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase /** * @dataProvider provideOutputFetchingMethods + * @expectedException \Symfony\Component\Process\Exception\LogicException + * @expectedExceptionMessage Output has been disabled. */ public function testGetOutputWhileDisabled($fetchMethod) { $p = $this->getProcess(self::$phpBin.' -r "usleep(500000);"'); $p->disableOutput(); $p->start(); - $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', 'Output has been disabled.'); $p->{$fetchMethod}(); } @@ -1139,6 +1182,37 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase array('getIncrementalErrorOutput'), ); } + + public function testStopTerminatesProcessCleanly() + { + $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); + $process->run(function () use ($process) { + $process->stop(); + }); + $this->assertTrue(true, 'A call to stop() is not expected to cause wait() to throw a RuntimeException'); + } + + public function testKillSignalTerminatesProcessCleanly() + { + $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); + $process->run(function () use ($process) { + if ($process->isRunning()) { + $process->signal(9); // SIGKILL + } + }); + $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException'); + } + + public function testTermSignalTerminatesProcessCleanly() + { + $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); + $process->run(function () use ($process) { + if ($process->isRunning()) { + $process->signal(15); // SIGTERM + } + }); + $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException'); + } public function responsesCodeProvider() { @@ -1202,7 +1276,38 @@ abstract class AbstractProcessTest extends \PHPUnit_Framework_TestCase * * @return Process */ - abstract protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()); + private function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) + { + $process = new Process($commandline, $cwd, $env, $input, $timeout, $options); + + if (false !== $enhance = getenv('ENHANCE_SIGCHLD')) { + try { + $process->setEnhanceSigchildCompatibility(false); + $process->getExitCode(); + $this->fail('ENHANCE_SIGCHLD must be used together with a sigchild-enabled PHP.'); + } catch (RuntimeException $e) { + $this->assertSame('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.', $e->getMessage()); + if ($enhance) { + $process->setEnhanceSigChildCompatibility(true); + } else { + self::$notEnhancedSigchild = true; + } + } + } + + return $process; + } + + private function skipIfNotEnhancedSigchild($expectException = true) + { + if (self::$notEnhancedSigchild) { + if ($expectException) { + $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild.'); + } else { + $this->markTestSkipped('PHP is compiled with --enable-sigchild and enhanced mode is disabled.'); + } + } + } } class Stringifiable diff --git a/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php b/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php deleted file mode 100644 index fdae5ec25e..0000000000 --- a/src/Symfony/Component/Process/Tests/SigchildDisabledProcessTest.php +++ /dev/null @@ -1,263 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -class SigchildDisabledProcessTest extends AbstractProcessTest -{ - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testGetExitCode() - { - parent::testGetExitCode(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testGetExitCodeIsNullOnStart() - { - parent::testGetExitCodeIsNullOnStart(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testGetExitCodeIsNullOnWhenStartingAgain() - { - parent::testGetExitCodeIsNullOnWhenStartingAgain(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testExitCodeCommandFailed() - { - parent::testExitCodeCommandFailed(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testMustRun() - { - parent::testMustRun(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testSuccessfulMustRunHasCorrectExitCode() - { - parent::testSuccessfulMustRunHasCorrectExitCode(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - */ - public function testMustRunThrowsException() - { - parent::testMustRunThrowsException(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - */ - public function testProcessIsSignaledIfStopped() - { - parent::testProcessIsSignaledIfStopped(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithTermSignal() - { - parent::testProcessWithTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessIsNotSignaled() - { - parent::testProcessIsNotSignaled(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignal() - { - parent::testProcessWithoutTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testCheckTimeoutOnStartedProcess() - { - parent::testCheckTimeoutOnStartedProcess(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPid() - { - parent::testGetPid(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullBeforeStart() - { - parent::testGetPidIsNullBeforeStart(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullAfterRun() - { - parent::testGetPidIsNullAfterRun(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testExitCodeText() - { - $process = $this->getProcess('qdfsmfkqsdfmqmsd'); - $process->run(); - - $process->getExitCodeText(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testExitCodeTextIsNullWhenExitCodeIsNull() - { - parent::testExitCodeTextIsNullWhenExitCodeIsNull(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testIsSuccessful() - { - parent::testIsSuccessful(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testIsSuccessfulOnlyAfterTerminated() - { - parent::testIsSuccessfulOnlyAfterTerminated(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testIsNotSuccessful() - { - parent::testIsNotSuccessful(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method. - */ - public function testTTYCommandExitCode() - { - parent::testTTYCommandExitCode(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process can not be signaled. - */ - public function testSignal() - { - parent::testSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignalIsNotSignaled() - { - parent::testProcessWithoutTermSignalIsNotSignaled(); - } - - public function testStopWithTimeoutIsActuallyWorking() - { - $this->markTestSkipped('Stopping with signal is not supported in sigchild environment'); - } - - public function testProcessThrowsExceptionWhenExternallySignaled() - { - $this->markTestSkipped('Retrieving Pid is not supported in sigchild environment'); - } - - public function testExitCodeIsAvailableAfterSignal() - { - $this->markTestSkipped('Signal is not supported in sigchild environment'); - } - - public function testRunProcessWithTimeout() - { - $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); - } - - public function provideStartMethods() - { - return array( - array('start', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'), - array('run', 'Symfony\Component\Process\Exception\LogicException', 'Output has been disabled, enable it to allow the use of a callback.'), - array('mustRun', 'Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.'), - ); - } - - /** - * {@inheritdoc} - */ - protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) - { - $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $input, $timeout, $options); - $process->setEnhanceSigchildCompatibility(false); - - return $process; - } -} diff --git a/src/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php b/src/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php deleted file mode 100644 index 645e6cf480..0000000000 --- a/src/Symfony/Component/Process/Tests/SigchildEnabledProcessTest.php +++ /dev/null @@ -1,152 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -class SigchildEnabledProcessTest extends AbstractProcessTest -{ - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessIsSignaledIfStopped() - { - parent::testProcessIsSignaledIfStopped(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithTermSignal() - { - parent::testProcessWithTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessIsNotSignaled() - { - parent::testProcessIsNotSignaled(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignal() - { - parent::testProcessWithoutTermSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPid() - { - parent::testGetPid(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullBeforeStart() - { - parent::testGetPidIsNullBeforeStart(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved. - */ - public function testGetPidIsNullAfterRun() - { - parent::testGetPidIsNullAfterRun(); - } - - public function testExitCodeText() - { - $process = $this->getProcess('qdfsmfkqsdfmqmsd'); - $process->run(); - - $this->assertInternalType('string', $process->getExitCodeText()); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. The process can not be signaled. - */ - public function testSignal() - { - parent::testSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\RuntimeException - * @expectedExceptionMessage This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved. - */ - public function testProcessWithoutTermSignalIsNotSignaled() - { - parent::testProcessWithoutTermSignalIsNotSignaled(); - } - - public function testProcessThrowsExceptionWhenExternallySignaled() - { - $this->markTestSkipped('Retrieving Pid is not supported in sigchild environment'); - } - - public function testExitCodeIsAvailableAfterSignal() - { - $this->markTestSkipped('Signal is not supported in sigchild environment'); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException - * @expectedExceptionMessage exceeded the timeout of 0.1 seconds. - */ - public function testStartAfterATimeout() - { - if ('\\' === DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Restarting a timed-out process on Windows is not supported in sigchild environment'); - } - parent::testStartAfterATimeout(); - } - - public function testStopWithTimeoutIsActuallyWorking() - { - $this->markTestSkipped('Stopping with signal is not supported in sigchild environment'); - } - - public function testRunProcessWithTimeout() - { - $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); - } - - public function testCheckTimeoutOnStartedProcess() - { - $this->markTestSkipped('Signal (required for timeout) is not supported in sigchild environment'); - } - - /** - * {@inheritdoc} - */ - protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) - { - $process = new ProcessInSigchildEnvironment($commandline, $cwd, $env, $input, $timeout, $options); - $process->setEnhanceSigchildCompatibility(true); - - return $process; - } -} diff --git a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php b/src/Symfony/Component/Process/Tests/SimpleProcessTest.php deleted file mode 100644 index 78f20eb100..0000000000 --- a/src/Symfony/Component/Process/Tests/SimpleProcessTest.php +++ /dev/null @@ -1,216 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Process\Tests; - -use Symfony\Component\Process\Process; - -class SimpleProcessTest extends AbstractProcessTest -{ - private $enabledSigchild = false; - - protected function setUp() - { - ob_start(); - phpinfo(INFO_GENERAL); - - $this->enabledSigchild = false !== strpos(ob_get_clean(), '--enable-sigchild'); - } - - public function testGetExitCode() - { - $this->skipIfPHPSigchild(); // This test use exitcode that is not available in this case - parent::testGetExitCode(); - } - - public function testExitCodeCommandFailed() - { - $this->skipIfPHPSigchild(); // This test use exitcode that is not available in this case - parent::testExitCodeCommandFailed(); - } - - public function testProcessIsSignaledIfStopped() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessIsSignaledIfStopped(); - } - - public function testProcessWithTermSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessWithTermSignal(); - } - - public function testProcessIsNotSignaled() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessIsNotSignaled(); - } - - public function testProcessWithoutTermSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessWithoutTermSignal(); - } - - public function testExitCodeText() - { - $this->skipIfPHPSigchild(); // This test use exitcode that is not available in this case - parent::testExitCodeText(); - } - - public function testIsSuccessful() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testIsSuccessful(); - } - - public function testIsNotSuccessful() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testIsNotSuccessful(); - } - - public function testGetPid() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testGetPid(); - } - - public function testGetPidIsNullBeforeStart() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testGetPidIsNullBeforeStart(); - } - - public function testGetPidIsNullAfterRun() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testGetPidIsNullAfterRun(); - } - - public function testSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - parent::testSignal(); - } - - public function testProcessWithoutTermSignalIsNotSignaled() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved'); - parent::testProcessWithoutTermSignalIsNotSignaled(); - } - - public function testProcessThrowsExceptionWhenExternallySignaled() - { - $this->skipIfPHPSigchild(); // This test use PID that is not available in this case - parent::testProcessThrowsExceptionWhenExternallySignaled(); - } - - public function testExitCodeIsAvailableAfterSignal() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - parent::testExitCodeIsAvailableAfterSignal(); - } - - /** - * @expectedException \Symfony\Component\Process\Exception\LogicException - * @expectedExceptionMessage Can not send signal on a non running process. - */ - public function testSignalProcessNotRunning() - { - parent::testSignalProcessNotRunning(); - } - - public function testSignalWithWrongIntSignal() - { - if ($this->enabledSigchild) { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - } else { - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Error while sending signal `-4`.'); - } - parent::testSignalWithWrongIntSignal(); - } - - public function testSignalWithWrongNonIntSignal() - { - if ($this->enabledSigchild) { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - } else { - $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'Error while sending signal `Céphalopodes`.'); - } - parent::testSignalWithWrongNonIntSignal(); - } - - public function testStopTerminatesProcessCleanly() - { - $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); - $process->run(function () use ($process) { - $process->stop(); - }); - $this->assertTrue(true, 'A call to stop() is not expected to cause wait() to throw a RuntimeException'); - } - - public function testKillSignalTerminatesProcessCleanly() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - - $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); - $process->run(function () use ($process) { - if ($process->isRunning()) { - $process->signal(defined('SIGKILL') ? SIGKILL : 9); - } - }); - $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException'); - } - - public function testTermSignalTerminatesProcessCleanly() - { - $this->expectExceptionIfPHPSigchild('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild. The process can not be signaled.'); - - $process = $this->getProcess(self::$phpBin.' -r "echo \'foo\'; sleep(1); echo \'bar\';"'); - $process->run(function () use ($process) { - if ($process->isRunning()) { - $process->signal(defined('SIGTERM') ? SIGTERM : 15); - } - }); - $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException'); - } - - public function testStopWithTimeoutIsActuallyWorking() - { - $this->skipIfPHPSigchild(); - - parent::testStopWithTimeoutIsActuallyWorking(); - } - - /** - * {@inheritdoc} - */ - protected function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = array()) - { - return new Process($commandline, $cwd, $env, $input, $timeout, $options); - } - - private function skipIfPHPSigchild() - { - if ($this->enabledSigchild) { - $this->markTestSkipped('Your PHP has been compiled with --enable-sigchild, this test can not be executed'); - } - } - - private function expectExceptionIfPHPSigchild($classname, $message) - { - if ($this->enabledSigchild) { - $this->setExpectedException($classname, $message); - } - } -} diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.lb.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.lb.xlf index 8281c7c249..d631797018 100644 --- a/src/Symfony/Component/Validator/Resources/translations/validators.lb.xlf +++ b/src/Symfony/Component/Validator/Resources/translations/validators.lb.xlf @@ -24,11 +24,11 @@ You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices. - Dir sollt mindestens {{ limit }} Méiglechkeete wielen. + Et muss mindestens {{ limit }} Méiglechkeet ausgewielt ginn.|Et musse mindestens {{ limit }} Méiglechkeeten ausgewielt ginn. You must select at most {{ limit }} choice.|You must select at most {{ limit }} choices. - Dir sollt héchstens {{ limit }} Méiglechkeete wielen. + Et dierf héchstens {{ limit }} Méiglechkeet ausgewielt ginn.|Et dierfen héchstens {{ limit }} Méiglechkeeten ausgewielt ginn. One or more of the given values is invalid. @@ -298,6 +298,22 @@ The image is portrait oriented ({{ width }}x{{ height }}px). Portrait oriented images are not allowed. D'Bild ass am Héichformat ({{ width }}x{{ height }}px). Biller am Héichformat sinn net erlaabt. + + An empty file is not allowed. + En eidele Fichier ass net erlaabt. + + + The host could not be resolved. + Den Domain-Numm konnt net opgeléist ginn. + + + This value does not match the expected {{ charset }} charset. + Dëse Wäert entsprécht net dem erwaarten Zeechesaz {{ charset }}. + + + This is not a valid Business Identifier Code (BIC). + Dëst ass kee gëltege "Business Identifier Code" (BIC). +