Permalink
Browse files

Unique token for child processes through environment variables

  • Loading branch information...
1 parent 648cd59 commit eb65da1fb13fa81457d80b58069448ad23761135 @dbaltas dbaltas committed Jan 30, 2013
@@ -8,6 +8,7 @@
protected $process;
protected $status;
protected $stderr;
+ protected $token;
protected static $descriptors = array(
0 => array('pipe', 'r'),
@@ -69,18 +70,19 @@ public function isDoneRunning()
}
/**
- * Called after a polling context to retrieve
+ * Called after a polling context to retrieve
* the exit code of the phpunit process
*/
public function getExitCode()
{
return $this->status['exitcode'];
}
- public function run($binary, $options = array())
+ public function run($binary, $options = array(), $environmentVariables = array())
{
$options = array_merge($this->prepareOptions($options), array('log-junit' => $this->getTempFile()));
- $command = $this->getCommandString($binary, $options);
+ $this->handleEnvironmentVariables($environmentVariables);
+ $command = $this->getCommandString($binary, $options, $environmentVariables);
$this->process = proc_open($command, self::$descriptors, $this->pipes);
return $this;
}
@@ -101,12 +103,25 @@ protected function prepareOptions($options)
return $options;
}
- protected function getCommandString($binary, $options = array())
+ protected function getCommandString($binary, $options = array(), $environmentVariables = array())
{
$command = $binary;
+ $environmentVariablePrefix = '';
+
foreach($options as $key => $value) $command .= " --$key %s";
- $args = array_merge(array("$command %s"), array_values($options), array($this->getPath()));
+ foreach($environmentVariables as $key => $value) $environmentVariablePrefix .= "$key=%s ";
+ $args = array_merge(array("$environmentVariablePrefix$command %s"), array_values($environmentVariables), array_values($options), array($this->getPath()));
$command = call_user_func_array('sprintf', $args);
return $command;
}
+
+ public function getToken()
+ {
+ return $this->token;
+ }
+
+ protected function handleEnvironmentVariables($environmentVariables)
+ {
+ if (isset($environmentVariables['TEST_TOKEN'])) $this->token = $environmentVariables['TEST_TOKEN'];
+ }
}
@@ -13,12 +13,14 @@ class Runner
protected $interpreter;
protected $printer;
protected $exitcode = -1;
-
+ protected $tokens = array();
+
public function __construct($opts = array())
{
$this->options = new Options($opts);
$this->interpreter = new LogInterpreter();
$this->printer = new ResultPrinter($this->interpreter);
+ $this->initTokens();
}
public function run()
@@ -28,7 +30,10 @@ public function run()
$this->printer->start($this->options);
while(count($this->running) || count($this->pending)) {
foreach($this->running as $key => $test)
- if(!$this->testIsStillRunning($test)) unset($this->running[$key]);
+ if(!$this->testIsStillRunning($test)) {
+ unset($this->running[$key]);
+ $this->releaseToken($key);
+ }
$this->fillRunQueue();
}
$this->complete();
@@ -78,8 +83,13 @@ private function log()
private function fillRunQueue()
{
$opts = $this->options;
- while(sizeof($this->pending) && sizeof($this->running) < $opts->processes)
- $this->running[] = array_shift($this->pending)->run($opts->phpunit, $opts->filtered);
+ while(sizeof($this->pending) && sizeof($this->running) < $opts->processes) {
+ $token = $this->getNextAvailableToken();
+ if ($token !== false) {
+ $this->acquireToken($token);
+ $this->running[$token] = array_shift($this->pending)->run($opts->phpunit, $opts->filtered, array('TEST_TOKEN' => $token));
+ }
+ }
}
private function testIsStillRunning($test)
@@ -99,4 +109,30 @@ private function setExitCode(ExecutableTest $test)
if($exit > $this->exitcode)
$this->exitcode = $exit;
}
+
+ protected function initTokens()
+ {
+ $this->tokens = array();
+ for ($i=0; $i< $this->options->processes; $i++) {
+ $this->tokens[$i] = true;
+ }
+ }
+
+ protected function getNextAvailableToken()
+ {
+ for ($i=0; $i< count($this->tokens); $i++) {
+ if ($this->tokens[$i]) return $i;
+ }
+ return false;
+ }
+
+ protected function releaseToken($tokenIdentifier)
+ {
+ $this->tokens[$tokenIdentifier] = true;
+ }
+
+ protected function acquireToken($tokenIdentifier)
+ {
+ $this->tokens[$tokenIdentifier] = false;
+ }
}
@@ -0,0 +1,58 @@
+<?php namespace ParaTest\Runners\PHPUnit;
+
+class ExecutableTestChild extends ExecutableTest
+{
+
+}
+
+class ExecutableTestTest extends \TestBase
+{
+ /**
+ *
+ * @var ExecutableTestChild
+ */
+ protected $executableTestChild;
+
+ public function setUp()
+ {
+ $this->executableTestChild = new ExecutableTestChild('pathToFile');
+ parent::setUp();
+ }
+
+ public function testConstructor()
+ {
+ $this->assertEquals('pathToFile', $this->getObjectValue($this->executableTestChild, 'path'));
+ }
+
+ public function testGetCommandStringIncludesOptions()
+ {
+ $options = array('bootstrap' => 'test/bootstrap.php');
+ $binary = '/usr/bin/phpunit';
+
+ $command = $this->call($this->executableTestChild, 'getCommandString', $binary, $options);
+ $this->assertEquals('/usr/bin/phpunit --bootstrap test/bootstrap.php pathToFile', $command);
+ }
+
+ public function testGetCommandStringIncludesEnvironmentVariables()
+ {
+ $options = array('bootstrap' => 'test/bootstrap.php');
+ $binary = '/usr/bin/phpunit';
+ $environmentVariables = array('TEST_TOKEN' => 3, 'APPLICATION_ENVIRONMENT_VAR' => 'abc');
+ $command = $this->call($this->executableTestChild, 'getCommandString', $binary, $options, $environmentVariables);
+
+ $this->assertEquals('TEST_TOKEN=3 APPLICATION_ENVIRONMENT_VAR=abc /usr/bin/phpunit --bootstrap test/bootstrap.php pathToFile', $command);
+ }
+
+ public function testHandleEnvironmentVariablesAssignsToken()
+ {
+ $environmentVariables = array('TEST_TOKEN' => 3, 'APPLICATION_ENVIRONMENT_VAR' => 'abc');
+ $this->call($this->executableTestChild, 'handleEnvironmentVariables', $environmentVariables);
+ $this->assertEquals(3, $this->getObjectValue($this->executableTestChild, 'token'));
+ }
+
+ public function testGetTokenReturnsValidToken()
+ {
+ $this->setObjectValue($this->executableTestChild, 'token', 3);
+ $this->assertEquals(3, $this->executableTestChild->getToken());
+ }
+}
@@ -34,4 +34,47 @@ public function testGetExitCode()
{
$this->assertEquals(-1, $this->runner->getExitCode());
}
+
+ public function testConstructorAssignsTokens()
+ {
+ $opts = array('processes' => 4, 'path' => FIXTURES . DS . 'tests', 'bootstrap' => 'hello', 'functional' => true);
+ $runner = new Runner($opts);
+ $tokens = $this->getObjectValue($runner, 'tokens');
+ $this->assertEquals(4, count($tokens));
+ }
+
+ public function testGetsNextAvailableTokenReturnsTokenIdentifier()
+ {
+ $tokens = array(0 => false, 1 => false, 2 => true, 3 => false);
+ $opts = array('processes' => 4, 'path' => FIXTURES . DS . 'tests', 'bootstrap' => 'hello', 'functional' => true);
+ $runner = new Runner($opts);
+ $this->setObjectValue($runner, 'tokens', $tokens);
+
+ $token = $this->call($runner, 'getNextAvailableToken');
+ $this->assertEquals(2, $token);
+ }
+
+ public function testGetNextAvailableTokenReturnsFalseWhenNoTokensAreAvailable()
+ {
+ $tokens = array(0 => false, 1 => false, 2 => false, 3 => false);
+ $opts = array('processes' => 4, 'path' => FIXTURES . DS . 'tests', 'bootstrap' => 'hello', 'functional' => true);
+ $runner = new Runner($opts);
+ $this->setObjectValue($runner, 'tokens', $tokens);
+
+ $token = $this->call($runner, 'getNextAvailableToken');
+ $this->assertTrue($token === false);
+ }
+
+ public function testReleaseTokenMakesTokenAvailable()
+ {
+ $tokens = array(0 => false, 1 => false, 2 => false, 3 => false);
+ $opts = array('processes' => 4, 'path' => FIXTURES . DS . 'tests', 'bootstrap' => 'hello', 'functional' => true);
+ $runner = new Runner($opts);
+ $this->setObjectValue($runner, 'tokens', $tokens);
+
+ $this->assertFalse($tokens[1]);
+ $this->call($runner, 'releaseToken', 1);
+ $tokens = $this->getObjectValue($runner, 'tokens');
+ $this->assertTrue($tokens[1]);
+ }
}
@@ -0,0 +1,10 @@
+<?php namespace ParaTest\Runners\PHPUnit;
+
+class TestMethodTest extends \TestBase
+{
+ public function testConstructor()
+ {
+ $testMethod = new TestMethod('pathToFile', 'methodName');
+ $this->assertEquals('pathToFile', $this->getObjectValue($testMethod, 'path'));
+ }
+}

0 comments on commit eb65da1

Please sign in to comment.