Re: [PHP-DEV] multi-jobs run-tests.php
hi, There is an on-going work on run-test (which began as part of last year GSoC). I would begin there instead of working on the current run-test.php. Parallel testing is part of the new features as well, in a portable way (like not only where pcntl is available). Thanks for your work, Cheers, -- Pierre On Mon, Feb 22, 2010 at 2:11 AM, Raphael Geissert geiss...@php.net wrote: Hi, I've spent the last hours working on making run-tests.php be able to run tests in parallel. The main reason being the time it takes to run the whole testsuite even on multicore CPUs. Attached is the first set of changes needed. It uses pcntl's fork and sysvmsg to send some of the results back to the parent process. Main functionalities still work, but the summary doesn't include failed tests. I plan to move away from sysvmsg because with the current implementation killing the parent process can leave message queues open (nothing that can't be fixed by adding a proper exit handler) and sysvmsg is not enabled by default. Probably to something php://memory-based. To support all the features under multi-jobs mode I think the proper fix is to cleanup the code so that run_test() stores the state information via an interface. This would make the code cleaner and would let multi-jobs mode just change the state-storing interface. How should I handle this? just by committing the changes? first sending them here (to internals)? by contacting somebody else? Cheers, -- Raphael Geissert -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- Pierre @pierrejoye | http://blog.thepimp.net | http://www.libgd.org -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] multi-jobs run-tests.php
forgot to add the link to the repo: http://svn.php.net/viewvc/php/phpruntests/ On Mon, Feb 22, 2010 at 9:20 AM, Pierre Joye pierre@gmail.com wrote: hi, There is an on-going work on run-test (which began as part of last year GSoC). I would begin there instead of working on the current run-test.php. Parallel testing is part of the new features as well, in a portable way (like not only where pcntl is available). Thanks for your work, Cheers, -- Pierre On Mon, Feb 22, 2010 at 2:11 AM, Raphael Geissert geiss...@php.net wrote: Hi, I've spent the last hours working on making run-tests.php be able to run tests in parallel. The main reason being the time it takes to run the whole testsuite even on multicore CPUs. Attached is the first set of changes needed. It uses pcntl's fork and sysvmsg to send some of the results back to the parent process. Main functionalities still work, but the summary doesn't include failed tests. I plan to move away from sysvmsg because with the current implementation killing the parent process can leave message queues open (nothing that can't be fixed by adding a proper exit handler) and sysvmsg is not enabled by default. Probably to something php://memory-based. To support all the features under multi-jobs mode I think the proper fix is to cleanup the code so that run_test() stores the state information via an interface. This would make the code cleaner and would let multi-jobs mode just change the state-storing interface. How should I handle this? just by committing the changes? first sending them here (to internals)? by contacting somebody else? Cheers, -- Raphael Geissert -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php -- Pierre @pierrejoye | http://blog.thepimp.net | http://www.libgd.org -- Pierre @pierrejoye | http://blog.thepimp.net | http://www.libgd.org -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] multi-jobs run-tests.php
Hi Pierre, Pierre Joye wrote: There is an on-going work on run-test (which began as part of last year GSoC). I would begin there instead of working on the current run-test.php. Parallel testing is part of the new features as well, in a portable way (like not only where pcntl is available). Ah, I see, great. From a quick look at the code it looks like it also uses pcntl. Is there any plan to switch to that other implementation? No work has been done in something like the threads extension, has there? Cheers, -- Raphael Geissert -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] multi-jobs run-tests.php
Hello all, While on the subject of run-tests.php, any plans for it to support web server SAPIs and not just CLI/CGI? I've looked at http://qa.php.net/projects.php and saw no such bullet but I thought asking anyhow won't hurt. Thanks, May the source be with you, Best regards, Jess Portnoy Raphael Geissert wrote: Hi Pierre, Pierre Joye wrote: There is an on-going work on run-test (which began as part of last year GSoC). I would begin there instead of working on the current run-test.php. Parallel testing is part of the new features as well, in a portable way (like not only where pcntl is available). Ah, I see, great. From a quick look at the code it looks like it also uses pcntl. Is there any plan to switch to that other implementation? No work has been done in something like the threads extension, has there? Cheers, -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-DEV] multi-jobs run-tests.php
On Mon, 2010-02-22 at 10:50 -0600, Raphael Geissert wrote: Ah, I see, great. From a quick look at the code it looks like it also uses pcntl. Is there any plan to switch to that other implementation? No work has been done in something like the threads extension, has there? Why would you need threads? - Won't some async process control be enough? - The test manager doesn't have to be parallelized, it should just run multiple tests at once. And yes, I'm very interested I have a 64 way SPARC machine which currently needs 7 days for a gcov run which, in theory, might be reduced to 7/64 days ... Another interesting thing might be directory-wide skipif so we don't have to run two PHP interpreters per test. But when working on all kinds of things there one should look on the rewrite by Zoe (and others) which should be nicer for modification than the grown code of the existing run-tests.php johannes -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-DEV] multi-jobs run-tests.php
Hi, I've spent the last hours working on making run-tests.php be able to run tests in parallel. The main reason being the time it takes to run the whole testsuite even on multicore CPUs. Attached is the first set of changes needed. It uses pcntl's fork and sysvmsg to send some of the results back to the parent process. Main functionalities still work, but the summary doesn't include failed tests. I plan to move away from sysvmsg because with the current implementation killing the parent process can leave message queues open (nothing that can't be fixed by adding a proper exit handler) and sysvmsg is not enabled by default. Probably to something php://memory-based. To support all the features under multi-jobs mode I think the proper fix is to cleanup the code so that run_test() stores the state information via an interface. This would make the code cleaner and would let multi-jobs mode just change the state-storing interface. How should I handle this? just by committing the changes? first sending them here (to internals)? by contacting somebody else? Cheers, -- Raphael Geissertdiff --git a/run-tests.php b/run-tests.php index 81f218b..9516490 100755 --- a/run-tests.php +++ b/run-tests.php @@ -451,6 +451,12 @@ if ($compression) { $output_file = 'compress.zlib://' . $output_file . '.gz'; } +$max_jobs = false; + +if (extension_loaded('pcntl') extension_loaded('sysvmsg')) { +$max_jobs = 1; +} + $just_save_results = false; $leak_check = false; $html_output = false; @@ -551,6 +557,14 @@ if (isset($argc) $argc 1) { $ini_overwrites[] = $argv[++$i]; break; //case 'h' +case 'j': + if ($max_jobs !== false) { + $max_jobs = (int)$argv[++$i]; + if ($max_jobs 1) { + $max_jobs = 1; + } + } + break; case '--keep-all': foreach($cfgfiles as $file) { $cfg['keep'][$file] = true; @@ -665,6 +679,9 @@ Options: -d foo=bar Pass -d option to the php binary (Define INI entry foo with value 'bar'). +-j n Maximum number of jobs to run in parallel (defaults to 1, +requires pcntl and sysvmsg). + -m Test for memory leaks with Valgrind. -p phpSpecify PHP executable to run. @@ -1082,9 +1099,30 @@ function system_with_timeout($commandline, $env = null, $stdin = null) return $data; } +function reap_jobs($queue, $results) +{ + // process messages aggresively to avoid + // saturating the queue, stalling childs + // waiting for space in the queue to exit + while (msg_receive($queue, 0, $null, 4096, $msg, true, MSG_IPC_NOWAIT)) + $results[$msg['index']] = $msg['result']; + return pcntl_wait($null); +} + function run_all_tests($test_files, $env, $redir_tested = null) { global $test_results, $failed_tests_file, $php, $test_cnt, $test_idx; + global $max_jobs; + + $run_once = 0; + + if ($max_jobs !== false) { + $jobs_avail = $max_jobs; + do { + $queue_key = mt_rand(); + } while (function_exists('msg_queue_exists') msg_queue_exists($queue_key)); + $queue = msg_get_queue($queue_key); + } foreach($test_files as $name) { @@ -1100,15 +1138,56 @@ function run_all_tests($test_files, $env, $redir_tested = null) $index = $name; } $test_idx++; + + if ($max_jobs ($max_jobs 1 || $jobs_avail == 0)) { + if (!$jobs_avail) { +if (reap_jobs($queue, $test_results) 0) +$jobs_avail++; + } + $pid = pcntl_fork(); + if ($pid == -1) { + // Do nothing special, test will be run by + // the parent process. + // Decrement $jobs_avail and $max_jobs so that if + // future calls to fork fail we will end up + // disabling multi-jobs support without + // leaving childs behind. + $jobs_avail--; + $max_jobs--; + } else if ($pid) { + // parent process + $jobs_avail--; + continue; + } else { + // child process: + $max_jobs = false; + $run_once = 1; + } + } + $result = run_test($php, $name, $env); if (!is_array($name) $result != 'REDIR') { - $test_results[$index] = $result; + // send the results back to the parent process + // if there's an active queue + if (isset($queue)) +msg_send($queue, 1, array('index' = $index, 'result' = $result)); + else +$test_results[$index] = $result; if ($failed_tests_file ($result == 'XFAILED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) { fwrite($failed_tests_file, $index\n); } } + if ($run_once) exit; } + + if ($max_jobs !== false) { + // check for messages one last time before removing the queue + // reap jobs at the same time + while (reap_jobs($queue, $test_results) 0); + msg_remove_queue($queue); + } + } // -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php