g2 Fri Jun 26 00:07:24 2009 UTC Added files: /phpruntests/src/taskScheduler rtTaskInterface.php rtTaskScheduler.php rtTaskSchedulerFile.php rtTask.php rtTaskSchedulerMsgQ.php rtTaskTestGroup.php /phpruntests/src/configuration/exceptions rtException.php /phpruntests/tests rtTaskSchedulerTest.php
Modified files: /phpruntests/src/configuration/exceptions rtEnvironmentException.php rtMissingArgumentException.php rtUnknownOptionException.php rtUnknownIniSettingException.php /phpruntests/src run-tests.php rtClassMap.php /phpruntests/src/configuration rtCommandLineOptions.php /phpruntests/src/testrun rtPhpTestRun.php Log: phpruntests - integrated taskScheduler into "rtPhpTestRun" - added argument for cmd-line-option 'z' (number of processes) - added rtExcpetion and a simple exception-hanlder
http://cvs.php.net/viewvc.cgi/phpruntests/src/configuration/exceptions/rtEnvironmentException.php?r1=1.2&r2=1.3&diff_format=u Index: phpruntests/src/configuration/exceptions/rtEnvironmentException.php diff -u phpruntests/src/configuration/exceptions/rtEnvironmentException.php:1.2 phpruntests/src/configuration/exceptions/rtEnvironmentException.php:1.3 --- phpruntests/src/configuration/exceptions/rtEnvironmentException.php:1.2 Mon Apr 20 20:24:30 2009 +++ phpruntests/src/configuration/exceptions/rtEnvironmentException.php Fri Jun 26 00:07:24 2009 @@ -1,6 +1,6 @@ <?php -class rtEnvironmentException extends RunTimeException +class rtEnvironmentException extends rtException { } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/configuration/exceptions/rtMissingArgumentException.php?r1=1.2&r2=1.3&diff_format=u Index: phpruntests/src/configuration/exceptions/rtMissingArgumentException.php diff -u phpruntests/src/configuration/exceptions/rtMissingArgumentException.php:1.2 phpruntests/src/configuration/exceptions/rtMissingArgumentException.php:1.3 --- phpruntests/src/configuration/exceptions/rtMissingArgumentException.php:1.2 Mon Apr 20 20:24:30 2009 +++ phpruntests/src/configuration/exceptions/rtMissingArgumentException.php Fri Jun 26 00:07:24 2009 @@ -1,6 +1,6 @@ <?php -class rtMissingArgumentException extends RuntimeException +class rtMissingArgumentException extends rtException { } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/configuration/exceptions/rtUnknownOptionException.php?r1=1.2&r2=1.3&diff_format=u Index: phpruntests/src/configuration/exceptions/rtUnknownOptionException.php diff -u phpruntests/src/configuration/exceptions/rtUnknownOptionException.php:1.2 phpruntests/src/configuration/exceptions/rtUnknownOptionException.php:1.3 --- phpruntests/src/configuration/exceptions/rtUnknownOptionException.php:1.2 Mon Apr 20 20:24:30 2009 +++ phpruntests/src/configuration/exceptions/rtUnknownOptionException.php Fri Jun 26 00:07:24 2009 @@ -1,6 +1,6 @@ <?php -class rtUnknownOptionException extends RuntimeException +class rtUnknownOptionException extends rtException { } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/configuration/exceptions/rtUnknownIniSettingException.php?r1=1.2&r2=1.3&diff_format=u Index: phpruntests/src/configuration/exceptions/rtUnknownIniSettingException.php diff -u phpruntests/src/configuration/exceptions/rtUnknownIniSettingException.php:1.2 phpruntests/src/configuration/exceptions/rtUnknownIniSettingException.php:1.3 --- phpruntests/src/configuration/exceptions/rtUnknownIniSettingException.php:1.2 Mon Apr 20 20:24:30 2009 +++ phpruntests/src/configuration/exceptions/rtUnknownIniSettingException.php Fri Jun 26 00:07:24 2009 @@ -1,6 +1,6 @@ <?php -class rtUnknownIniSettingException extends RuntimeException +class rtUnknownIniSettingException extends rtException { } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/run-tests.php?r1=1.3&r2=1.4&diff_format=u Index: phpruntests/src/run-tests.php diff -u phpruntests/src/run-tests.php:1.3 phpruntests/src/run-tests.php:1.4 --- phpruntests/src/run-tests.php:1.3 Tue May 12 16:05:00 2009 +++ phpruntests/src/run-tests.php Fri Jun 26 00:07:24 2009 @@ -4,6 +4,22 @@ */ + +/** + * rtExceptionHandler + * + * @param Exception $e + * @return unknown_type + */ +function rtExceptionHandler(Exception $e) { + + print $e; +} + +set_exception_handler('rtExceptionHandler'); + + + /* * check the version of the running php-executable and * ensure that is 5.3 or higher @@ -14,7 +30,13 @@ require_once dirname(__FILE__) . '/rtAutoload.php'; +$s = microtime(true); + $phpTestRun = new rtPhpTestRun($argv); $phpTestRun->run(); +$e = microtime(true); + +print "\n".($e-$s)." sec\n\n"; + ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/rtClassMap.php?r1=1.13&r2=1.14&diff_format=u Index: phpruntests/src/rtClassMap.php diff -u phpruntests/src/rtClassMap.php:1.13 phpruntests/src/rtClassMap.php:1.14 --- phpruntests/src/rtClassMap.php:1.13 Tue Jun 23 12:59:51 2009 +++ phpruntests/src/rtClassMap.php Fri Jun 26 00:07:24 2009 @@ -8,6 +8,7 @@ */ $rtClassMap = array( 'rtEnvironmentException' => 'configuration/exceptions/rtEnvironmentException.php', + 'rtException' => 'configuration/exceptions/rtException.php', 'rtMissingArgumentException' => 'configuration/exceptions/rtMissingArgumentException.php', 'rtUnknownIniSettingException' => 'configuration/exceptions/rtUnknownIniSettingException.php', 'rtUnknownOptionException' => 'configuration/exceptions/rtUnknownOptionException.php', @@ -48,6 +49,12 @@ 'rtPhptFilterIterator' => 'rtPhptFilterIterator.php', 'rtText' => 'rtText.php', 'rtUtil' => 'rtUtil.php', + 'rtTask' => 'taskScheduler/rtTask.php', + 'rtTaskInterface' => 'taskScheduler/rtTaskInterface.php', + 'rtTaskScheduler' => 'taskScheduler/rtTaskScheduler.php', + 'rtTaskSchedulerFile' => 'taskScheduler/rtTaskSchedulerFile.php', + 'rtTaskSchedulerMsgQ' => 'taskScheduler/rtTaskSchedulerMsgQ.php', + 'rtTaskTestGroup' => 'taskScheduler/rtTaskTestGroup.php', 'rtPhpRunnerException' => 'testcase/exceptions/rtPhpRunnerException.php', 'rtTestOutputWriterList' => 'testcase/output/rtTestOutputWriterList.php', 'rtTestOutputWriterXML' => 'testcase/output/rtTestOutputWriterXML.php', http://cvs.php.net/viewvc.cgi/phpruntests/src/configuration/rtCommandLineOptions.php?r1=1.5&r2=1.6&diff_format=u Index: phpruntests/src/configuration/rtCommandLineOptions.php diff -u phpruntests/src/configuration/rtCommandLineOptions.php:1.5 phpruntests/src/configuration/rtCommandLineOptions.php:1.6 --- phpruntests/src/configuration/rtCommandLineOptions.php:1.5 Mon May 25 08:56:23 2009 +++ phpruntests/src/configuration/rtCommandLineOptions.php Fri Jun 26 00:07:24 2009 @@ -24,8 +24,7 @@ 'q', 'x', 'v', - 'h', - 'z', //parallel - run out of obvious letters + 'h', ); /** @@ -40,6 +39,7 @@ 'd', 'p', 's', + 'z', //parallel - run out of obvious letters ); /** http://cvs.php.net/viewvc.cgi/phpruntests/src/testrun/rtPhpTestRun.php?r1=1.11&r2=1.12&diff_format=u Index: phpruntests/src/testrun/rtPhpTestRun.php diff -u phpruntests/src/testrun/rtPhpTestRun.php:1.11 phpruntests/src/testrun/rtPhpTestRun.php:1.12 --- phpruntests/src/testrun/rtPhpTestRun.php:1.11 Sun Jun 7 11:06:51 2009 +++ phpruntests/src/testrun/rtPhpTestRun.php Fri Jun 26 00:07:24 2009 @@ -8,6 +8,7 @@ * @package RUNTESTS * @author Zoe Slattery <z...@php.net> * @author Stefan Priebsch <sprieb...@php.net> + * @author Georg Gradwohl <g...@php.net> * @copyright 2009 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License 3.01 * @@ -39,16 +40,43 @@ if ($runConfiguration->getSetting('TestDirectories') != null) { foreach ($runConfiguration->getSetting('TestDirectories') as $testDirectory) { - - //make list of subdirectories which contain tests, includes the top level directory - $subDirectories = rtUtil::getDirectoryList($testDirectory); - - //Run tests in each subdirectory in sequence - foreach ($subDirectories as $subDirectory) { - $testGroup = new rtPhpTestGroup($runConfiguration, $subDirectory); - $testGroup->runGroup($runConfiguration); - $testGroup->writeGroup(); - } + + // make list of subdirectories which contain tests, includes the top level directory + $subDirectories = rtUtil::parseDir($testDirectory); + + // check for the cmd-line-option 'z' which defines parellel-execution + if ($runConfiguration->hasCommandLineOption('z')) { + + $processCount = $runConfiguration->getCommandLineOption('z'); + + if (!is_numeric($processCount) || $processCount <= 0) { + $processCount = sizeof($subDirectories); + } + + // create the task-list + $taskList = array(); + foreach ($subDirectories as $subDirectory) { + $taskList[] = new rtTaskTestGroup(&$runConfiguration, &$subDirectory); + } + + + // start the task-scheduler for multi-processing + $scheduler = rtTaskScheduler::getInstance(); + $scheduler->setTaskList($taskList); + $scheduler->setProcessCount($processCount); + $scheduler->run(); + $scheduler->printStatistic(); + + } else { + + //Run tests in each subdirectory in sequence + foreach ($subDirectories as $subDirectory) { + $testGroup = new rtPhpTestGroup($runConfiguration, $subDirectory); + $testGroup->runGroup($runConfiguration); + // $testGroup->writeGroup(); + } + + } } //*have a directory or list of directories to test. http://cvs.php.net/viewvc.cgi/phpruntests/src/taskScheduler/rtTaskInterface.php?view=markup&rev=1.1 Index: phpruntests/src/taskScheduler/rtTaskInterface.php +++ phpruntests/src/taskScheduler/rtTaskInterface.php <?php interface rtTaskInterface { public function run(); } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/taskScheduler/rtTaskScheduler.php?view=markup&rev=1.1 Index: phpruntests/src/taskScheduler/rtTaskScheduler.php +++ phpruntests/src/taskScheduler/rtTaskScheduler.php <?php /** * rtTaskScheduler * * Main class of the TaskScheduler * * @category Testing * @package RUNTESTS * @author Zoe Slattery <z...@php.net> * @author Stefan Priebsch <sprieb...@php.net> * @author Georg Gradwohl <g...@php.net> * @copyright 2009 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License 3.01 * */ class rtTaskScheduler { protected $taskList = array(); // the list of the tasks to be executed protected $processCount = 0; // the number of processes protected $time = 0; // the needed time protected $countPass = 0; // counts the passed tasks protected $countFail = 0; // counts the failed tasks protected $memStore = array(); // stores the mem-usage after an incomming task /** * the constructor * * @param array $taskList (optional) * @param int $processCount (optional) */ public function __construct(array $taskList=NULL, $processCount=NULL) { if (is_array($taskList)) { $this->setTaskList($taskList); } $this->setProcessCount($processCount); } public static function getInstance(array $taskList=NULL, $processCount=NUL, $useMsgQ=false) { // TODO: remove this statement and check this by runtime-config if (extension_loaded('pcntl')) { if ($useMsgQ === true) { return new rtTaskSchedulerMsgQ($taskList, $processCount); } return new rtTaskSchedulerFile($taskList, $processCount); } return new rtTaskScheduler($taskList, $processCount); } /** * sets the task-list which has to be an array of task-objects. * * @param array $taskList */ public function setTaskList(array $taskList) { $this->taskList = $taskList; } /** * @return array $taskList */ public function getTaskList() { return $this->taskList; } /** * sets the number of child-processes. * in the case of using a multidimensional task-list this parameter is * ignored and set to the number of task-groups. * * @param int $count */ public function setProcessCount($processCount) { if (is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** * executes the tasks in a simple loop * * @return void */ public function run() { $s = microtime(true); for ($i=0; $i<sizeof($this->taskList); $i++) { $task = $this->taskList[$i]; if ($task->run() === true) { $task->setState(task::PASS); $this->countPass++; } else { $task->setState(task::FAIL); $this->countFail++; } $this->memStore[] = memory_get_usage(true); print "."; flush(); $this->taskList[$i] = $task; } $error = microtime(true); $this->time = round($error-$s,5); return; } /** * prints the statistic * * @return void */ public function printStatistic() { print "\n----------------------------------------\n"; /* if (is_array($this->taskList[0])) { $count = 0; foreach ($this->taskList as $list) { $count += sizeof($list); } print "Groups:\t\t".sizeof($this->taskList)."\n"; print "Tasks:\t\t".$count."\n"; } else { $count = sizeof($this->taskList); print "Tasks:\t\t".$count."\n"; } print "PASSED:\t\t".$this->countPass." ("....@round($this->countPass/$count*100,2)."%)\n"; print "FAILED:\t\t".$this->countFail." ("....@round($this->countFail/$count*100,2)."%)\n"; */ $count = sizeof($this->taskList); print "Test-Groups:\t".$count."\n"; print "Processes:\t".$this->processCount."\n"; print "Seconds:\t".$this->time."\n"; if ($this->processCount > 0 && sizeof($this->memStore) > 0) { print "AVG sec/task:\t"....@round($this->time/$this->processCount,5)."\n"; print "Memory-MAX:\t".number_format(@max($this->memStore))."\n"; print "Memory-MIN:\t".number_format(@min($this->memStore))."\n"; $avg = array_sum($this->memStore)/sizeof($this->memStore); print "Memory-AVG:\t".number_format($avg)."\n"; } print "----------------------------------------\n"; flush(); } /** * prints a overview of the faild tasks * * @return void */ public function printFailedTasks() { if ($this->countFail > 0) { print "FAILED TASKS"; print "\n----------------------------------------\n"; for ($i=0; $i<sizeof($this->taskList); $i++) { $task = $this->taskList[$i]; if ($task->getState() == task::FAIL) { print "Task $i: ".$task->getMessage()."\n"; } } print "----------------------------------------\n"; flush(); } } public function printMemStatistic($int=10) { print "MEMORY-USAGE"; print "\n----------------------------------------\n"; $int = ceil(sizeof($this->memStore)/$int); $title = "TASK:\t"; $body = "kB:\t"; for ($i=0; $i<sizeof($this->memStore); $i+=$int) { $title .= "$i\t"; $body .= round($this->memStore[$i]/1000)."\t"; } print $title."\n".$body; print "\n----------------------------------------\n"; flush(); } } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/taskScheduler/rtTaskSchedulerFile.php?view=markup&rev=1.1 Index: phpruntests/src/taskScheduler/rtTaskSchedulerFile.php +++ phpruntests/src/taskScheduler/rtTaskSchedulerFile.php <?php /** * rtTaskSchedulerFile * * extention of TaskScheduler, implements a ipc via temporary files * * @category Testing * @package RUNTESTS * @author Zoe Slattery <z...@php.net> * @author Stefan Priebsch <sprieb...@php.net> * @author Georg Gradwohl <g...@php.net> * @copyright 2009 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License 3.01 * */ class rtTaskSchedulerFile extends rtTaskScheduler { const TMP_FILE = 'taskFile'; private $inputQueue = NULL; // the input-queue (only used by the sender) private $pidStore = array(); // stores the pids of all child-processes private $groupTasks = false; // are the tasks stored in groups? private $tmpTaskList = array(); /** * the constructor * * @param array $taskList (optional) * @param int $processCount (optional) */ public function __construct(array $taskList=NULL, $processCount=NULL) { if (is_array($taskList)) { $this->setTaskList($taskList); } $this->setProcessCount($processCount); } /** * sets the task-list which has to be an array of task-objects. * it's also possible to use a multidimensional array. in this case the * tasks are distributed to the child-processes exactly in the way as they * are grouped in the list. the first-level index strictly has to be * numeric and continuous starting with zero. * * @param array $taskList * @Overrides */ public function setTaskList(array $taskList) { if (is_array($taskList[0])) { $this->groupTasks = true; $this->processCount = sizeof($taskList); } $this->taskList = $taskList; } /** * sets the number of child-processes. * in the case of using a multidimensional task-list this parameter is * ignored and set to the number of task-groups. * * @param int $count * @Overrides */ public function setProcessCount($processCount) { if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** * starts the sender, the receiver and forks the defined * number of child-processes. * * @return void * @Overrides */ public function run() { if ($this->processCount == 0) { return parent::run(); } $startTime = microtime(true); // trim the processCount if nesecarry if ($this->processCount > sizeof($this->taskList)) { $this->processCount = sizeof($this->taskList); } $this->createTaskFiles(); // fork the child-processes for ($i=0; $i<$this->processCount; $i++) { $this->pidStore[$i] = pcntl_fork(); switch ($this->pidStore[$i]) { case -1: // failure die("could not fork"); break; case 0: // child $this->child($i); break; default: // parent break; } } // wait until all child-processes are terminated for ($i=0; $i<$this->processCount; $i++) { pcntl_waitpid($this->pidStore[$i], $status); } // ensure that the tmp-files are completly written sleep(1); // collecting the results $this->receiver(); $endTime = microtime(true); $this->time = round($endTime-$startTime,5); return; } /** * creates a temporary file for each child which stores the allocated * array-indices. * */ private function createTaskFiles() { $taskStr = array(); if ($this->groupTasks == true) { $c = 0; foreach ($this->taskList as $key => $list) { for ($i=0; $i<sizeof($list); $i++) { $taskStr[$key] .= $i.';'; } } } else { for ($i=0; $i<sizeof($this->taskList); $i++) { $taskStr[$i%$this->processCount] .= $i.';'; } } for ($i=0; $i<$this->processCount; $i++) { file_put_contents(self::TMP_FILE.$i, $taskStr[$i]); } } /** * @return void */ private function receiver() { for ($cid=0; $cid<$this->processCount; $cid++) { $response = file_get_contents(self::TMP_FILE.$cid); $response = explode("\n", $response); array_pop($response); foreach ($response as $task) { $task = unserialize($task); if ($task->getState() == rtTask::PASS) { $this->countPass++; } else { $this->countFail++; } $index = $task->getIndex(); if ($this->groupTasks == true) { $this->taskList[$cid][$index] = $task; } else { $this->taskList[$index] = $task; } } unlink(self::TMP_FILE.$cid); } return; } /** * @param int $cid the child-id * @return void */ private function child($cid) { $indexList = file_get_contents(self::TMP_FILE.$cid); $indexList = explode(';', $indexList); array_pop($indexList); $response = ''; foreach ($indexList as $index) { if ($this->groupTasks == true) { $task = $this->taskList[$cid][$index]; } else { $task = $this->taskList[$index]; } if ($task->run() === true) { $task->setState(rtTask::PASS); } else { $task->setState(rtTask::FAIL); } $task->setIndex($index); $response .= serialize($task)."\n"; } file_put_contents(self::TMP_FILE.$cid, $response); exit(0); } } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/taskScheduler/rtTask.php?view=markup&rev=1.1 Index: phpruntests/src/taskScheduler/rtTask.php +++ phpruntests/src/taskScheduler/rtTask.php <?php abstract class rtTask { const NOEX = 0; const PASS = 1; const FAIL = -1; private $state = self::NOEX; private $index = NULL; private $message = NULL; public function setState($state) { $this->state = $state; } public function getState() { return $this->state; } public function setMessage($msg) { $this->message = $msg; } public function getMessage() { return $this->message; } public function setIndex($index) { $this->index = $index; } public function getIndex() { return $this->index; } } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/taskScheduler/rtTaskSchedulerMsgQ.php?view=markup&rev=1.1 Index: phpruntests/src/taskScheduler/rtTaskSchedulerMsgQ.php +++ phpruntests/src/taskScheduler/rtTaskSchedulerMsgQ.php <?php /** * rtTaskSchedulerMsgQ * * extention of TaskScheduler, implements a ipc via message-queues * * @category Testing * @package RUNTESTS * @author Zoe Slattery <z...@php.net> * @author Stefan Priebsch <sprieb...@php.net> * @author Georg Gradwohl <g...@php.net> * @copyright 2009 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License 3.01 * */ declare(ticks=true); class rtTaskSchedulerMsgQ extends rtTaskScheduler { const MSG_QUEUE_KEY = 1234; // id of the message-queue const MSG_QUEUE_SIZE = 1024; // max-size of a single message const KILL_CHILD = 'killBill'; // kill-signal to terminate a child private $inputQueue = NULL; // the input-queue (only used by the sender) private $pidStore = array(); // stores the pids of all child-processes private $groupTasks = false; // are the tasks stored in groups? /** * sets the task-list which has to be an array of task-objects. * it's also possible to use a multidimensional array. in this case the * tasks are distributed to the child-processes exactly in the way as they * are grouped in the list. the first-level index strictly has to be * numeric and continuous starting with zero. * * @param array $taskList * @Overrides */ public function setTaskList(array $taskList) { if (is_array($taskList[0])) { $this->groupTasks = true; $this->processCount = sizeof($taskList); } $this->taskList = $taskList; } /** * sets the number of child-processes. * in the case of using a multidimensional task-list this parameter is * ignored and set to the number of task-groups. * * @param int $count * @Overrides */ public function setProcessCount($processCount) { if ($this->groupTasks !== true && is_numeric($processCount) && $processCount >= 0) { $this->processCount = $processCount; } } /** * removes the used message-queues. */ private static function cleanUp() { @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY)); @msg_remove_queue(msg_get_queue(self::MSG_QUEUE_KEY+1)); } /** * the signal-handler is called by the interrupt- or quit-signal and calls * the cleanUp-method. * * @param int $signal */ public static function signalHandler($signal) { switch($signal) { case SIGINT: case SIGQUIT: self::cleanUp(); die("\n"); break; default: break; } } /** * starts the sender, the receiver and forks the defined * number of child-processes. * * @return void * @Overrides */ public function run() { if ($this->processCount == 0) { return parent::run(); } $startTime = microtime(true); // register signal-handler pcntl_signal(SIGINT, "taskSchedulerMsgQ::signalHandler"); pcntl_signal(SIGQUIT, "taskSchedulerMsgQ::signalHandler"); // trim the processCount if nesecarry if ($this->processCount > sizeof($this->taskList)) { $this->processCount = sizeof($this->taskList); } // fork the child-processes for ($i=0; $i<=$this->processCount; $i++) { $this->pidStore[$i] = pcntl_fork(); switch ($this->pidStore[$i]) { case -1: // failure die("could not fork"); break; case 0: // child if ($i==0) { $this->sender(); } else { $cid = ($this->groupTasks == true) ? $i : NULL; $this->child($cid); } break; default: // parent break; } } // start the receiver $this->receiver(); // wait until all child-processes are terminated for ($i=0; $i<=$this->processCount; $i++) { pcntl_waitpid($this->pidStore[$i], $status); } $endTime = microtime(true); $this->time = round($endTime-$startTime,5); // remove the msg-queue self::cleanUp(); return; } /** * the receiver is listening to the result-queue and stores the incomming * tasks back to the task-list. * when finished it sends the kill-signal to all children and terminates * itself. * * @return void */ private function receiver() { $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); $task = ''; $type = 1; if ($this->groupTasks == true) { $limit = 0; foreach ($this->taskList as $list) { $limit += sizeof($list); } } else { $limit = sizeof($this->taskList); } for ($i=0; $i<$limit; $i++) { $this->memStore[] = memory_get_usage(true); if (msg_receive($resultQueue, 0, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { // check state if ($task->getState() == rtTask::PASS) { $this->countPass++; } else { $this->countFail++; } // store result $index = $task->getIndex(); if ($this->groupTasks == true) { $this->taskList[$type-2][$index] = $task; } else { $this->taskList[$index] = $task; } } else { print "RECEIVER ERROR $error\n"; } } $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); for ($i=1; $i<=$this->processCount; $i++) { if (msg_send($inputQueue, $i, self::KILL_CHILD, true, true, $error)) { } else { print "RECEIVER ERROR $error\n"; } } return; } /** * the sender is passes through the task-list and distributes the single * tasks to the child-processes using the input-queue. * when finished it terminates itself. * * @return void */ private function sender() { $this->inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); for ($i=0; $i<sizeof($this->taskList); $i++) { if ($this->groupTasks == true) { for ($j=0; $j<sizeof($this->taskList[$i]); $j++) { $this->sendTask($this->taskList[$i][$j], $j, $i+1); } } else { $this->sendTask($this->taskList[$i], $i); } } exit(0); } /** * helper-class of sender. * sends a task to a child-process using the input-queue. * * @param task $task the task to send * @param int $index the task's index in the taskList * @param int $type the message-type (default=1) * @return void */ private function sendTask(task $task, $index, $type=1) { $task->setIndex($index); if (msg_send($this->inputQueue, $type, $task, true, true, $error)) { } else { print "SENDER ERROR $error\n"; } return; } /** * the child is listening to the input-queue and executes the incomming * tasks. afterwards it setts the task-state and sends it back to the * receiver via the result-queue. * after receiving the kill-signal from the receiver it terminates itself. * * @param int $cid the child-id (default=NULL) * @return void */ private function child($cid=NULL) { if (is_null($cid)) { $cid = 0; } $inputQueue = msg_get_queue(self::MSG_QUEUE_KEY); $resultQueue = msg_get_queue(self::MSG_QUEUE_KEY+1); $type = 1; while (true) { if (msg_receive($inputQueue, $cid, $type, self::MSG_QUEUE_SIZE, $task, true, NULL, $error)) { if ($task == self::KILL_CHILD) break; $index = $task->getIndex(); if ($task->run() === true) { $task->setState(rtTask::PASS); } else { $task->setState(rtTask::FAIL); } print "."; flush(); if (msg_send($resultQueue, $cid+1, $task, true, true, $error)) { } else { print "CHILD ERROR $error\n"; } } else { print "CHILD ERROR $error\n"; } } exit(0); } } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/taskScheduler/rtTaskTestGroup.php?view=markup&rev=1.1 Index: phpruntests/src/taskScheduler/rtTaskTestGroup.php +++ phpruntests/src/taskScheduler/rtTaskTestGroup.php <?php /** * rtTaskTestGroup * * @category Testing * @package RUNTESTS * @author Zoe Slattery <z...@php.net> * @author Stefan Priebsch <sprieb...@php.net> * @author Georg Gradwohl <g...@php.net> * @copyright 2009 The PHP Group * @license http://www.php.net/license/3_01.txt PHP License 3.01 * */ class rtTaskTestGroup extends rtTask implements rtTaskInterface { private $runConfiguration; private $subDirectory; public function __construct($runConfiguration, $subDirectory) { $this->runConfiguration = $runConfiguration; $this->subDirectory = $subDirectory; } public function run() { $testGroup = new rtPhpTestGroup($this->runConfiguration, $this->subDirectory); $testGroup->runGroup($this->runConfiguration); // $testGroup->writeGroup(); return true; } public function getDir() { return $this->subDirectory; } } ?> http://cvs.php.net/viewvc.cgi/phpruntests/src/configuration/exceptions/rtException.php?view=markup&rev=1.1 Index: phpruntests/src/configuration/exceptions/rtException.php +++ phpruntests/src/configuration/exceptions/rtException.php <?php class rtException extends RuntimeException { public function __toString() { $r = "\n--------------------------------------------------------------------------------\n"; $r .= "EXCEPTION\n"; $r .= $this->getMessage()." (CODE ".$this->getCode().")\n"; $r .= $this->getFile().":".$this->getLine()."\n\n"; $r .= $this->getTraceAsString(); $r .= "\n--------------------------------------------------------------------------------\n"; return $r; } } ?> http://cvs.php.net/viewvc.cgi/phpruntests/tests/rtTaskSchedulerTest.php?view=markup&rev=1.1 Index: phpruntests/tests/rtTaskSchedulerTest.php +++ phpruntests/tests/rtTaskSchedulerTest.php <?php require_once 'PHPUnit/Framework.php'; require_once dirname(__FILE__) . '/../src/rtAutoload.php'; class rtTaskSchedulerTest extends PHPUnit_Framework_TestCase { public function testResult() { // create 10 tasks with random numbers $taskList = array(); $expected = array(); for ($i=0; $i<10; $i++) { $n = rand(0,9); $expected[$i] = $n+1; $taskList[$i] = new rtTaskIncTest($n); } // run the task-scheduler $scheduler = rtTaskScheduler::getInstance(); $scheduler->setTaskList($taskList); $scheduler->setProcessCount(3); $scheduler->run(); // get the results from the manupilated task-list $results = array(); foreach ($scheduler->getTaskList() as $task) { $results[] = $task->getNumber(); } $this->assertEquals($expected, $results); } } /** * rtTaskIncTest * * nested helper-class for rtTaskSchedulerTest */ class rtTaskIncTest extends rtTask implements rtTaskInterface { private $num = null; public function __construct($num) { $this->num = $num; } public function run() { $this->num++; return true; } public function getNumber() { return $this->num; } } ?>
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php