Back to index

php5  5.3.10
run-tests.php
Go to the documentation of this file.
00001 #!/usr/bin/php
00002 <?php
00003 /*
00004    +----------------------------------------------------------------------+
00005    | PHP Version 5                                                        |
00006    +----------------------------------------------------------------------+
00007    | Copyright (c) 1997-2010 The PHP Group                                |
00008    +----------------------------------------------------------------------+
00009    | This source file is subject to version 3.01 of the PHP license,      |
00010    | that is bundled with this package in the file LICENSE, and is        |
00011    | available through the world-wide-web at the following url:           |
00012    | http://www.php.net/license/3_01.txt                                  |
00013    | If you did not receive a copy of the PHP license and are unable to   |
00014    | obtain it through the world-wide-web, please send a note to          |
00015    | license@php.net so we can mail you a copy immediately.               |
00016    +----------------------------------------------------------------------+
00017    | Authors: Ilia Alshanetsky <iliaa@php.net>                            |
00018    |          Preston L. Bannister <pbannister@php.net>                   |
00019    |          Marcus Boerger <helly@php.net>                              |
00020    |          Derick Rethans <derick@php.net>                             |
00021    |          Sander Roobol <sander@php.net>                              |
00022    | (based on version by: Stig Bakken <ssb@php.net>)                     |
00023    | (based on the PHP 3 test framework by Rasmus Lerdorf)                |
00024    +----------------------------------------------------------------------+
00025  */
00026 
00027 /* $Id: run-tests.php 320475 2011-12-06 05:44:54Z derick $ */
00028 
00029 /* Sanity check to ensure that pcre extension needed by this script is available.
00030  * In the event it is not, print a nice error message indicating that this script will
00031  * not run without it.
00032  */
00033 
00034 if (!extension_loaded('pcre')) {
00035        echo <<<NO_PCRE_ERROR
00036 
00037 +-----------------------------------------------------------+
00038 |                       ! ERROR !                           |
00039 | The test-suite requires that you have pcre extension      |
00040 | enabled. To enable this extension either compile your PHP |
00041 | with --with-pcre-regex or if you've compiled pcre as a    |
00042 | shared module load it via php.ini.                        |
00043 +-----------------------------------------------------------+
00044 
00045 NO_PCRE_ERROR;
00046 exit;
00047 }
00048 
00049 if (!function_exists('proc_open')) {
00050        echo <<<NO_PROC_OPEN_ERROR
00051 
00052 +-----------------------------------------------------------+
00053 |                       ! ERROR !                           |
00054 | The test-suite requires that proc_open() is available.    |
00055 | Please check if you disabled it in php.ini.               |
00056 +-----------------------------------------------------------+
00057 
00058 NO_PROC_OPEN_ERROR;
00059 exit;
00060 }
00061 
00062 // Version constants only available as of 5.2.8
00063 if (!defined("PHP_VERSION_ID")) {
00064        list($major, $minor, $bug) = explode(".", phpversion(), 3);
00065        $bug = (int)$bug; // Many distros make up their own versions
00066        if ($bug < 10) {
00067               $bug = "0$bug";
00068        }
00069 
00070        define("PHP_VERSION_ID", "{$major}0{$minor}$bug");
00071        define("PHP_MAJOR_VERSION", $major);
00072 }
00073 
00074 // __DIR__ is available from 5.3.0
00075 if (PHP_VERSION_ID < 50300) {
00076        define('__DIR__', realpath(dirname(__FILE__)));
00077        // FILE_BINARY is available from 5.2.7
00078        if (PHP_VERSION_ID < 50207) {
00079               define('FILE_BINARY', 0);
00080        }
00081 }
00082 
00083 // If timezone is not set, use UTC.
00084 if (ini_get('date.timezone') == '') {
00085        date_default_timezone_set('UTC');
00086 }
00087 
00088 // store current directory
00089 $CUR_DIR = getcwd();
00090 
00091 // change into the PHP source directory.
00092 
00093 if (getenv('TEST_PHP_SRCDIR')) {
00094        @chdir(getenv('TEST_PHP_SRCDIR'));
00095 }
00096 
00097 // Delete some security related environment variables
00098 putenv('SSH_CLIENT=deleted');
00099 putenv('SSH_AUTH_SOCK=deleted');
00100 putenv('SSH_TTY=deleted');
00101 putenv('SSH_CONNECTION=deleted');
00102 
00103 $cwd = getcwd();
00104 set_time_limit(0);
00105 
00106 ini_set('pcre.backtrack_limit', PHP_INT_MAX);
00107 
00108 $valgrind_version = 0;
00109 $valgrind_header = '';
00110 
00111 // delete as much output buffers as possible
00112 while(@ob_end_clean());
00113 if (ob_get_level()) echo "Not all buffers were deleted.\n";
00114 
00115 error_reporting(E_ALL);
00116 if (PHP_MAJOR_VERSION < 6) {
00117        ini_set('magic_quotes_runtime',0); // this would break tests by modifying EXPECT sections
00118        if (ini_get('safe_mode')) {
00119               echo <<< SAFE_MODE_WARNING
00120 
00121 +-----------------------------------------------------------+
00122 |                       ! WARNING !                         |
00123 | You are running the test-suite with "safe_mode" ENABLED ! |
00124 |                                                           |
00125 | Chances are high that no test will work at all,           |
00126 | depending on how you configured "safe_mode" !             |
00127 +-----------------------------------------------------------+
00128 
00129 
00130 SAFE_MODE_WARNING;
00131        }
00132 }
00133 
00134 $environment = isset($_ENV) ? $_ENV : array();
00135 if ((substr(PHP_OS, 0, 3) == "WIN") && empty($environment["SystemRoot"])) {
00136   $environment["SystemRoot"] = getenv("SystemRoot");
00137 }
00138 
00139 // Don't ever guess at the PHP executable location.
00140 // Require the explicit specification.
00141 // Otherwise we could end up testing the wrong file!
00142 
00143 $php = null;
00144 $php_cgi = null;
00145 
00146 if (getenv('TEST_PHP_EXECUTABLE')) {
00147        $php = getenv('TEST_PHP_EXECUTABLE');
00148 
00149        if ($php=='auto') {
00150               $php = $cwd . '/sapi/cli/php';
00151               putenv("TEST_PHP_EXECUTABLE=$php");
00152 
00153               if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
00154                      $php_cgi = $cwd . '/sapi/cgi/php-cgi';
00155 
00156                      if (file_exists($php_cgi)) {
00157                             putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi");
00158                      } else {
00159                             $php_cgi = null;
00160                      }
00161               }
00162        }
00163        $environment['TEST_PHP_EXECUTABLE'] = $php;
00164 }
00165 
00166 if (getenv('TEST_PHP_CGI_EXECUTABLE')) {
00167        $php_cgi = getenv('TEST_PHP_CGI_EXECUTABLE');
00168 
00169        if ($php_cgi=='auto') {
00170               $php_cgi = $cwd . '/sapi/cgi/php-cgi';
00171               putenv("TEST_PHP_CGI_EXECUTABLE=$php_cgi");
00172        }
00173 
00174        $environment['TEST_PHP_CGI_EXECUTABLE'] = $php_cgi;
00175 }
00176 
00177 function verify_config()
00178 {
00179        global $php;
00180 
00181        if (empty($php) || !file_exists($php)) {
00182               error('environment variable TEST_PHP_EXECUTABLE must be set to specify PHP executable!');
00183        }
00184 
00185        if (function_exists('is_executable') && !is_executable($php)) {
00186               error("invalid PHP executable specified by TEST_PHP_EXECUTABLE  = $php");
00187        }
00188 }
00189 
00190 if (getenv('TEST_PHP_LOG_FORMAT')) {
00191        $log_format = strtoupper(getenv('TEST_PHP_LOG_FORMAT'));
00192 } else {
00193        $log_format = 'LEODS';
00194 }
00195 
00196 // Check whether a detailed log is wanted.
00197 if (getenv('TEST_PHP_DETAILED')) {
00198        $DETAILED = getenv('TEST_PHP_DETAILED');
00199 } else {
00200        $DETAILED = 0;
00201 }
00202 
00203 // Check whether a junit log is wanted.
00204 $JUNIT = getenv('TEST_PHP_JUNIT');
00205 if (empty($JUNIT) || (!file_exists($JUNIT) && !is_writable(dirname($JUNIT))) || (file_exists($JUNIT) && !is_writable($JUNIT)) || !($JUNIT = @fopen($JUNIT, 'w'))) {
00206        $JUNIT = FALSE;
00207 }
00208 else{
00209        $JUNIT = array(
00210               'fp'            => $JUNIT,
00211               'test_total'    => 0,
00212               'test_pass'     => 0,
00213               'test_fail'     => 0,
00214               'test_error'    => 0,
00215               'test_skip'     => 0,
00216               'started_at'    => microtime(true),
00217               'finished_at'   => NULL,
00218               'execution_time'=> NULL,
00219               'result_xml'    => '',
00220        );
00221 }
00222 
00223 if (getenv('SHOW_ONLY_GROUPS')) {
00224        $SHOW_ONLY_GROUPS = explode(",", getenv('SHOW_ONLY_GROUPS'));
00225 } else {
00226        $SHOW_ONLY_GROUPS = array();
00227 }
00228 
00229 // Check whether user test dirs are requested.
00230 if (getenv('TEST_PHP_USER')) {
00231        $user_tests = explode (',', getenv('TEST_PHP_USER'));
00232 } else {
00233        $user_tests = array();
00234 }
00235 
00236 $exts_to_test = array();
00237 $ini_overwrites = array(
00238               'output_handler=',
00239               'open_basedir=',
00240               'safe_mode=0',
00241               'disable_functions=',
00242               'output_buffering=Off',
00243               'error_reporting=' . (E_ALL | E_STRICT),
00244               'display_errors=1',
00245               'display_startup_errors=1',
00246               'log_errors=0',
00247               'html_errors=0',
00248               'track_errors=1',
00249               'report_memleaks=1',
00250               'report_zend_debug=0',
00251               'docref_root=',
00252               'docref_ext=.html',
00253               'error_prepend_string=',
00254               'error_append_string=',
00255               'auto_prepend_file=',
00256               'auto_append_file=',
00257               'magic_quotes_runtime=0',
00258               'ignore_repeated_errors=0',
00259               'precision=14',
00260               'unicode.runtime_encoding=ISO-8859-1',
00261               'unicode.script_encoding=UTF-8',
00262               'unicode.output_encoding=UTF-8',
00263               'unicode.from_error_mode=U_INVALID_SUBSTITUTE',
00264        );
00265 
00266 function write_information($show_html)
00267 {
00268        global $cwd, $php, $php_cgi, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test, $leak_check, $valgrind_header;
00269 
00270        // Get info from php
00271        $info_file = __DIR__ . '/run-test-info.php';
00272        @unlink($info_file);
00273        $php_info = '<?php echo "
00274 PHP_SAPI    : " , PHP_SAPI , "
00275 PHP_VERSION : " , phpversion() , "
00276 ZEND_VERSION: " , zend_version() , "
00277 PHP_OS      : " , PHP_OS , " - " , php_uname() , "
00278 INI actual  : " , realpath(get_cfg_var("cfg_file_path")) , "
00279 More .INIs  : " , (function_exists(\'php_ini_scanned_files\') ? str_replace("\n","", php_ini_scanned_files()) : "** not determined **"); ?>';
00280        save_text($info_file, $php_info);
00281        $info_params = array();
00282        settings2array($ini_overwrites, $info_params);
00283        settings2params($info_params);
00284        $php_info = `$php $pass_options $info_params "$info_file"`;
00285        define('TESTED_PHP_VERSION', `$php -n -r "echo PHP_VERSION;"`);
00286 
00287        if ($php_cgi && $php != $php_cgi) {
00288               $php_info_cgi = `$php_cgi $pass_options $info_params -q "$info_file"`;
00289               $php_info_sep = "\n---------------------------------------------------------------------";
00290               $php_cgi_info = "$php_info_sep\nPHP         : $php_cgi $php_info_cgi$php_info_sep";
00291        } else {
00292               $php_cgi_info = '';
00293        }
00294 
00295        @unlink($info_file);
00296 
00297        // load list of enabled extensions
00298        save_text($info_file, '<?php echo join(",", get_loaded_extensions()); ?>');
00299        $exts_to_test = explode(',',`$php $pass_options $info_params "$info_file"`);
00300        // check for extensions that need special handling and regenerate
00301        $info_params_ex = array(
00302               'session' => array('session.auto_start=0'),
00303               'tidy' => array('tidy.clean_output=0'),
00304               'zlib' => array('zlib.output_compression=Off'),
00305               'xdebug' => array('xdebug.default_enable=0'),
00306               'mbstring' => array('mbstring.func_overload=0'),
00307        );
00308 
00309        foreach($info_params_ex as $ext => $ini_overwrites_ex) {
00310               if (in_array($ext, $exts_to_test)) {
00311                      $ini_overwrites = array_merge($ini_overwrites, $ini_overwrites_ex);
00312               }
00313        }
00314 
00315        @unlink($info_file);
00316 
00317        // Write test context information.
00318        echo "
00319 =====================================================================
00320 PHP         : $php $php_info $php_cgi_info
00321 CWD         : $cwd
00322 Extra dirs  : ";
00323        foreach ($user_tests as $test_dir) {
00324               echo "{$test_dir}\n              ";
00325        }
00326        echo "
00327 VALGRIND    : " . ($leak_check ? $valgrind_header : 'Not used') . "
00328 =====================================================================
00329 ";
00330 }
00331 
00332 define('PHP_QA_EMAIL', 'qa-reports@lists.php.net');
00333 define('QA_SUBMISSION_PAGE', 'http://qa.php.net/buildtest-process.php');
00334 define('QA_REPORTS_PAGE', 'http://qa.php.net/reports');
00335 
00336 function save_or_mail_results()
00337 {
00338        global $sum_results, $just_save_results, $failed_test_summary,
00339               $PHP_FAILED_TESTS, $CUR_DIR, $php, $output_file, $compression;
00340 
00341        /* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */
00342        if (!getenv('NO_INTERACTION')) {
00343               $fp = fopen("php://stdin", "r+");
00344               if ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['WARNED'] || $sum_results['LEAKED'] || $sum_results['XFAILED']) {
00345                      echo "\nYou may have found a problem in PHP.";
00346               }
00347               echo "\nThis report can be automatically sent to the PHP QA team at\n";
00348               echo QA_REPORTS_PAGE . " and http://news.php.net/php.qa.reports\n";
00349               echo "This gives us a better understanding of PHP's behavior.\n";
00350               echo "If you don't want to send the report immediately you can choose\n";
00351               echo "option \"s\" to save it.     You can then email it to ". PHP_QA_EMAIL . " later.\n";
00352               echo "Do you want to send this report now? [Yns]: ";
00353               flush();
00354 
00355               $user_input = fgets($fp, 10);
00356               $just_save_results = (strtolower($user_input[0]) == 's');
00357        }
00358 
00359        if ($just_save_results || !getenv('NO_INTERACTION')) {
00360               if ($just_save_results || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') {
00361                      /*
00362                       * Collect information about the host system for our report
00363                       * Fetch phpinfo() output so that we can see the PHP enviroment
00364                       * Make an archive of all the failed tests
00365                       * Send an email
00366                       */
00367                      if ($just_save_results) {
00368                             $user_input = 's';
00369                      }
00370 
00371                      /* Ask the user to provide an email address, so that QA team can contact the user */
00372                      if (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) {
00373                             echo "\nPlease enter your email address.\n(Your address will be mangled so that it will not go out on any\nmailinglist in plain text): ";
00374                             flush();
00375                             $user_email = trim(fgets($fp, 1024));
00376                             $user_email = str_replace("@", " at ", str_replace(".", " dot ", $user_email));
00377                      }
00378 
00379                      $failed_tests_data = '';
00380                      $sep = "\n" . str_repeat('=', 80) . "\n";
00381                      $failed_tests_data .= $failed_test_summary . "\n";
00382                      $failed_tests_data .= get_summary(true, false) . "\n";
00383 
00384                      if ($sum_results['FAILED']) {
00385                             foreach ($PHP_FAILED_TESTS['FAILED'] as $test_info) {
00386                                    $failed_tests_data .= $sep . $test_info['name'] . $test_info['info'];
00387                                    $failed_tests_data .= $sep . file_get_contents(realpath($test_info['output']), FILE_BINARY);
00388                                    $failed_tests_data .= $sep . file_get_contents(realpath($test_info['diff']), FILE_BINARY);
00389                                    $failed_tests_data .= $sep . "\n\n";
00390                             }
00391                             $status = "failed";
00392                      } else {
00393                             $status = "success";
00394                      }
00395 
00396                      $failed_tests_data .= "\n" . $sep . 'BUILD ENVIRONMENT' . $sep;
00397                      $failed_tests_data .= "OS:\n" . PHP_OS . " - " . php_uname() . "\n\n";
00398                      $ldd = $autoconf = $sys_libtool = $libtool = $compiler = 'N/A';
00399 
00400                      if (substr(PHP_OS, 0, 3) != "WIN") {
00401                             /* If PHP_AUTOCONF is set, use it; otherwise, use 'autoconf'. */
00402                             if (getenv('PHP_AUTOCONF')) {
00403                                    $autoconf = shell_exec(getenv('PHP_AUTOCONF') . ' --version');
00404                             } else {
00405                                    $autoconf = shell_exec('autoconf --version');
00406                             }
00407 
00408                             /* Always use the generated libtool - Mac OSX uses 'glibtool' */
00409                             $libtool = shell_exec($CUR_DIR . '/libtool --version');
00410 
00411                             /* Use shtool to find out if there is glibtool present (MacOSX) */
00412                             $sys_libtool_path = shell_exec(__DIR__ . '/build/shtool path glibtool libtool');
00413 
00414                             if ($sys_libtool_path) {
00415                                    $sys_libtool = shell_exec(str_replace("\n", "", $sys_libtool_path) . ' --version');
00416                             }
00417 
00418                             /* Try the most common flags for 'version' */
00419                             $flags = array('-v', '-V', '--version');
00420                             $cc_status = 0;
00421 
00422                             foreach($flags AS $flag) {
00423                                    system(getenv('CC') . " $flag >/dev/null 2>&1", $cc_status);
00424                                    if ($cc_status == 0) {
00425                                           $compiler = shell_exec(getenv('CC') . " $flag 2>&1");
00426                                           break;
00427                                    }
00428                             }
00429 
00430                             $ldd = shell_exec("ldd $php 2>/dev/null");
00431                      }
00432 
00433                      $failed_tests_data .= "Autoconf:\n$autoconf\n";
00434                      $failed_tests_data .= "Bundled Libtool:\n$libtool\n";
00435                      $failed_tests_data .= "System Libtool:\n$sys_libtool\n";
00436                      $failed_tests_data .= "Compiler:\n$compiler\n";
00437                      $failed_tests_data .= "Bison:\n". shell_exec('bison --version 2>/dev/null') . "\n";
00438                      $failed_tests_data .= "Libraries:\n$ldd\n";
00439                      $failed_tests_data .= "\n";
00440 
00441                      if (isset($user_email)) {
00442                             $failed_tests_data .= "User's E-mail: " . $user_email . "\n\n";
00443                      }
00444 
00445                      $failed_tests_data .= $sep . "PHPINFO" . $sep;
00446                      $failed_tests_data .= shell_exec($php . ' -ddisplay_errors=stderr -dhtml_errors=0 -i 2> /dev/null');
00447 
00448                      if ($just_save_results || !mail_qa_team($failed_tests_data, $compression, $status)) {
00449                             file_put_contents($output_file, $failed_tests_data);
00450 
00451                             if (!$just_save_results) {
00452                                    echo "\nThe test script was unable to automatically send the report to PHP's QA Team\n";
00453                             }
00454 
00455                             echo "Please send " . $output_file . " to " . PHP_QA_EMAIL . " manually, thank you.\n";
00456                      } else {
00457                             fwrite($fp, "\nThank you for helping to make PHP better.\n");
00458                             fclose($fp);
00459                      }
00460               }
00461        }
00462 }
00463 
00464 // Determine the tests to be run.
00465 
00466 $test_files = array();
00467 $redir_tests = array();
00468 $test_results = array();
00469 $PHP_FAILED_TESTS = array('BORKED' => array(), 'FAILED' => array(), 'WARNED' => array(), 'LEAKED' => array(), 'XFAILED' => array());
00470 
00471 // If parameters given assume they represent selected tests to run.
00472 $failed_tests_file= false;
00473 $pass_option_n = false;
00474 $pass_options = '';
00475 
00476 $compression = 0;
00477 $output_file = $CUR_DIR . '/php_test_results_' . date('Ymd_Hi') . '.txt';
00478 
00479 if ($compression) {
00480        $output_file = 'compress.zlib://' . $output_file . '.gz';
00481 }
00482 
00483 $just_save_results = false;
00484 $leak_check = false;
00485 $html_output = false;
00486 $html_file = null;
00487 $temp_source = null;
00488 $temp_target = null;
00489 $temp_urlbase = null;
00490 $conf_passed = null;
00491 $no_clean = false;
00492 
00493 $cfgtypes = array('show', 'keep');
00494 $cfgfiles = array('skip', 'php', 'clean', 'out', 'diff', 'exp');
00495 $cfg = array();
00496 
00497 foreach($cfgtypes as $type) {
00498        $cfg[$type] = array();
00499 
00500        foreach($cfgfiles as $file) {
00501               $cfg[$type][$file] = false;
00502        }
00503 }
00504 
00505 if (getenv('TEST_PHP_ARGS')) {
00506 
00507        if (!isset($argc) || !$argc || !isset($argv)) {
00508               $argv = array(__FILE__);
00509        }
00510 
00511        $argv = array_merge($argv, explode(' ', getenv('TEST_PHP_ARGS')));
00512        $argc = count($argv);
00513 }
00514 
00515 if (isset($argc) && $argc > 1) {
00516 
00517        for ($i=1; $i<$argc; $i++) {
00518               $is_switch = false;
00519               $switch = substr($argv[$i],1,1);
00520               $repeat = substr($argv[$i],0,1) == '-';
00521 
00522               while ($repeat) {
00523 
00524                      if (!$is_switch) {
00525                             $switch = substr($argv[$i],1,1);
00526                      }
00527 
00528                      $is_switch = true;
00529 
00530                      if ($repeat) {
00531                             foreach($cfgtypes as $type) {
00532                                    if (strpos($switch, '--' . $type) === 0) {
00533                                           foreach($cfgfiles as $file) {
00534                                                  if ($switch == '--' . $type . '-' . $file) {
00535                                                         $cfg[$type][$file] = true;
00536                                                         $is_switch = false;
00537                                                         break;
00538                                                  }
00539                                           }
00540                                    }
00541                             }
00542                      }
00543 
00544                      if (!$is_switch) {
00545                             $is_switch = true;
00546                             break;
00547                      }
00548 
00549                      $repeat = false;
00550 
00551                      switch($switch) {
00552                             case 'r':
00553                             case 'l':
00554                                    $test_list = file($argv[++$i]);
00555                                    if ($test_list) {
00556                                           foreach($test_list as $test) {
00557                                                  $matches = array();
00558                                                  if (preg_match('/^#.*\[(.*)\]\:\s+(.*)$/', $test, $matches)) {
00559                                                         $redir_tests[] = array($matches[1], $matches[2]);
00560                                                  } else if (strlen($test)) {
00561                                                         $test_files[] = trim($test);
00562                                                  }
00563                                           }
00564                                    }
00565                                    if ($switch != 'l') {
00566                                           break;
00567                                    }
00568                                    $i--;
00569                                    // break left intentionally
00570                             case 'w':
00571                                    $failed_tests_file = fopen($argv[++$i], 'w+t');
00572                                    break;
00573                             case 'a':
00574                                    $failed_tests_file = fopen($argv[++$i], 'a+t');
00575                                    break;
00576                             case 'c':
00577                                    $conf_passed = $argv[++$i];
00578                                    break;
00579                             case 'd':
00580                                    $ini_overwrites[] = $argv[++$i];
00581                                    break;
00582                             case 'g':
00583                                    $SHOW_ONLY_GROUPS = explode(",", $argv[++$i]);;
00584                                    break;
00585                             //case 'h'
00586                             case '--keep-all':
00587                                    foreach($cfgfiles as $file) {
00588                                           $cfg['keep'][$file] = true;
00589                                    }
00590                                    break;
00591                             //case 'l'
00592                             case 'm':
00593                                    $leak_check = true;
00594                                    $valgrind_cmd = "valgrind --version";
00595                                    $valgrind_header = system_with_timeout($valgrind_cmd, $environment);
00596                                    $replace_count = 0;
00597                                    if (!$valgrind_header) {
00598                                           error("Valgrind returned no version info, cannot proceed.\nPlease check if Valgrind is installed.");
00599                                    } else {
00600                                           $valgrind_version = preg_replace("/valgrind-([0-9])\.([0-9])\.([0-9]+)([.-\w]+)?(\s+)/", '$1$2$3', $valgrind_header, 1, $replace_count);
00601                                           if ($replace_count != 1 || !is_numeric($valgrind_version)) {
00602                                                  error("Valgrind returned invalid version info (\"$valgrind_header\"), cannot proceed.");
00603                                           }
00604                                           $valgrind_header = trim($valgrind_header);
00605                                    }
00606                                    break;
00607                             case 'n':
00608                                    if (!$pass_option_n) {
00609                                           $pass_options .= ' -n';
00610                                    }
00611                                    $pass_option_n = true;
00612                                    break;
00613                             case '--no-clean':
00614                                    $no_clean = true;
00615                                    break;
00616                             case 'p':
00617                                    $php = $argv[++$i];
00618                                    putenv("TEST_PHP_EXECUTABLE=$php");
00619                                    $environment['TEST_PHP_EXECUTABLE'] = $php;
00620                                    break;
00621                             case 'q':
00622                                    putenv('NO_INTERACTION=1');
00623                                    break;
00624                             //case 'r'
00625                             case 's':
00626                                    $output_file = $argv[++$i];
00627                                    $just_save_results = true;
00628                                    break;
00629                             case '--set-timeout':
00630                                    $environment['TEST_TIMEOUT'] = $argv[++$i];
00631                                    break;
00632                             case '--show-all':
00633                                    foreach($cfgfiles as $file) {
00634                                           $cfg['show'][$file] = true;
00635                                    }
00636                                    break;
00637                             case '--temp-source':
00638                                    $temp_source = $argv[++$i];
00639                                    break;
00640                             case '--temp-target':
00641                                    $temp_target = $argv[++$i];
00642                                    if ($temp_urlbase) {
00643                                           $temp_urlbase = $temp_target;
00644                                    }
00645                                    break;
00646                             case '--temp-urlbase':
00647                                    $temp_urlbase = $argv[++$i];
00648                                    break;
00649                             case 'v':
00650                             case '--verbose':
00651                                    $DETAILED = true;
00652                                    break;
00653                             case 'x':
00654                                    $environment['SKIP_SLOW_TESTS'] = 1;
00655                                    break;
00656                             //case 'w'
00657                             case '-':
00658                                    // repeat check with full switch
00659                                    $switch = $argv[$i];
00660                                    if ($switch != '-') {
00661                                           $repeat = true;
00662                                    }
00663                                    break;
00664                             case '--html':
00665                                    $html_file = fopen($argv[++$i], 'wt');
00666                                    $html_output = is_resource($html_file);
00667                                    break;
00668                             case '--version':
00669                                    echo '$Revision: 320475 $' . "\n";
00670                                    exit(1);
00671 
00672                             default:
00673                                    echo "Illegal switch '$switch' specified!\n";
00674                             case 'h':
00675                             case '-help':
00676                             case '--help':
00677                                    echo <<<HELP
00678 Synopsis:
00679     php run-tests.php [options] [files] [directories]
00680 
00681 Options:
00682     -l <file>   Read the testfiles to be executed from <file>. After the test
00683                 has finished all failed tests are written to the same <file>.
00684                 If the list is empty and no further test is specified then
00685                 all tests are executed (same as: -r <file> -w <file>).
00686 
00687     -r <file>   Read the testfiles to be executed from <file>.
00688 
00689     -w <file>   Write a list of all failed tests to <file>.
00690 
00691     -a <file>   Same as -w but append rather then truncating <file>.
00692 
00693     -c <file>   Look for php.ini in directory <file> or use <file> as ini.
00694 
00695     -n          Pass -n option to the php binary (Do not use a php.ini).
00696 
00697     -d foo=bar  Pass -d option to the php binary (Define INI entry foo
00698                 with value 'bar').
00699 
00700     -g          Comma seperated list of groups to show during test run
00701                 (possible values: PASS, FAIL, XFAIL, SKIP, BORK, WARN, LEAK, REDIRECT).
00702 
00703     -m          Test for memory leaks with Valgrind.
00704 
00705     -p <php>    Specify PHP executable to run.
00706 
00707     -q          Quiet, no user interaction (same as environment NO_INTERACTION).
00708 
00709     -s <file>   Write output to <file>.
00710 
00711     -x          Sets 'SKIP_SLOW_TESTS' environmental variable.
00712 
00713     --verbose
00714     -v          Verbose mode.
00715 
00716     --help
00717     -h          This Help.
00718 
00719     --html <file> Generate HTML output.
00720 
00721     --temp-source <sdir>  --temp-target <tdir> [--temp-urlbase <url>]
00722                 Write temporary files to <tdir> by replacing <sdir> from the
00723                 filenames to generate with <tdir>. If --html is being used and
00724                 <url> given then the generated links are relative and prefixed
00725                 with the given url. In general you want to make <sdir> the path
00726                 to your source files and <tdir> some pach in your web page
00727                 hierarchy with <url> pointing to <tdir>.
00728 
00729     --keep-[all|php|skip|clean]
00730                 Do not delete 'all' files, 'php' test file, 'skip' or 'clean'
00731                 file.
00732 
00733     --set-timeout [n]
00734                 Set timeout for individual tests, where [n] is the number of
00735                 seconds. The default value is 60 seconds, or 300 seconds when
00736                 testing for memory leaks.
00737 
00738     --show-[all|php|skip|clean|exp|diff|out]
00739                 Show 'all' files, 'php' test file, 'skip' or 'clean' file. You
00740                 can also use this to show the output 'out', the expected result
00741                 'exp' or the difference between them 'diff'. The result types
00742                 get written independent of the log format, however 'diff' only
00743                 exists when a test fails.
00744 
00745     --no-clean  Do not execute clean section if any.
00746 
00747 HELP;
00748                                    exit(1);
00749                      }
00750               }
00751 
00752               if (!$is_switch) {
00753                      $testfile = realpath($argv[$i]);
00754 
00755                      if (!$testfile && strpos($argv[$i], '*') !== false && function_exists('glob')) {
00756 
00757                             if (preg_match("/\.phpt$/", $argv[$i])) {
00758                                    $pattern_match = glob($argv[$i]);
00759                             } else if (preg_match("/\*$/", $argv[$i])) {
00760                                    $pattern_match = glob($argv[$i] . '.phpt');
00761                             } else {
00762                                    die("bogus test name " . $argv[$i] . "\n");
00763                             }
00764 
00765                             if (is_array($pattern_match)) {
00766                                    $test_files = array_merge($test_files, $pattern_match);
00767                             }
00768 
00769                      } else if (is_dir($testfile)) {
00770                             find_files($testfile);
00771                      } else if (preg_match("/\.phpt$/", $testfile)) {
00772                             $test_files[] = $testfile;
00773                      } else {
00774                             die("bogus test name " . $argv[$i] . "\n");
00775                      }
00776               }
00777        }
00778 
00779        if (strlen($conf_passed)) {
00780               if (substr(PHP_OS, 0, 3) == "WIN") {
00781                      $pass_options .= " -c " . escapeshellarg($conf_passed);
00782               } else {
00783                      $pass_options .= " -c '$conf_passed'";
00784               }
00785        }
00786 
00787        $test_files = array_unique($test_files);
00788        $test_files = array_merge($test_files, $redir_tests);
00789 
00790        // Run selected tests.
00791        $test_cnt = count($test_files);
00792 
00793        if ($test_cnt) {
00794               putenv('NO_INTERACTION=1');
00795               verify_config();
00796               write_information($html_output);
00797               usort($test_files, "test_sort");
00798               $start_time = time();
00799 
00800               if (!$html_output) {
00801                      echo "Running selected tests.\n";
00802               } else {
00803                      show_start($start_time);
00804               }
00805 
00806               $test_idx = 0;
00807               run_all_tests($test_files, $environment);
00808               $end_time = time();
00809 
00810               if ($html_output) {
00811                      show_end($end_time);
00812               }
00813 
00814               if ($failed_tests_file) {
00815                      fclose($failed_tests_file);
00816               }
00817 
00818               if (count($test_files) || count($test_results)) {
00819                      compute_summary();
00820                      if ($html_output) {
00821                             fwrite($html_file, "<hr/>\n" . get_summary(false, true));
00822                      }
00823                      echo "=====================================================================";
00824                      echo get_summary(false, false);
00825               }
00826 
00827               if ($html_output) {
00828                      fclose($html_file);
00829               }
00830 
00831               if ($output_file != '' && $just_save_results) {
00832                      save_or_mail_results();
00833               }
00834               
00835               if ($JUNIT) {
00836                      save_junit_xml();
00837               }
00838 
00839               if (getenv('REPORT_EXIT_STATUS') == 1 and preg_match('/FAILED(?: |$)/', implode(' ', $test_results))) {
00840                      exit(1);
00841               }
00842 
00843               exit(0);
00844        }
00845 }
00846 
00847 verify_config();
00848 write_information($html_output);
00849 
00850 // Compile a list of all test files (*.phpt).
00851 $test_files = array();
00852 $exts_tested = count($exts_to_test);
00853 $exts_skipped = 0;
00854 $ignored_by_ext = 0;
00855 sort($exts_to_test);
00856 $test_dirs = array();
00857 $optionals = array('tests', 'ext', 'Zend', 'ZendEngine2', 'sapi/cli', 'sapi/cgi');
00858 
00859 foreach($optionals as $dir) {
00860        if (@filetype($dir) == 'dir') {
00861               $test_dirs[] = $dir;
00862        }
00863 }
00864 
00865 // Convert extension names to lowercase
00866 foreach ($exts_to_test as $key => $val) {
00867        $exts_to_test[$key] = strtolower($val);
00868 }
00869 
00870 foreach ($test_dirs as $dir) {
00871        find_files("{$cwd}/{$dir}", ($dir == 'ext'));
00872 }
00873 
00874 foreach ($user_tests as $dir) {
00875        find_files($dir, ($dir == 'ext'));
00876 }
00877 
00878 function find_files($dir, $is_ext_dir = false, $ignore = false)
00879 {
00880        global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped, $exts_tested;
00881 
00882        $o = opendir($dir) or error("cannot open directory: $dir");
00883 
00884        while (($name = readdir($o)) !== false) {
00885 
00886               if (is_dir("{$dir}/{$name}") && !in_array($name, array('.', '..', '.svn'))) {
00887                      $skip_ext = ($is_ext_dir && !in_array(strtolower($name), $exts_to_test));
00888                      if ($skip_ext) {
00889                             $exts_skipped++;
00890                      }
00891                      find_files("{$dir}/{$name}", false, $ignore || $skip_ext);
00892               }
00893 
00894               // Cleanup any left-over tmp files from last run.
00895               if (substr($name, -4) == '.tmp') {
00896                      @unlink("$dir/$name");
00897                      continue;
00898               }
00899 
00900               // Otherwise we're only interested in *.phpt files.
00901               if (substr($name, -5) == '.phpt') {
00902                      if ($ignore) {
00903                             $ignored_by_ext++;
00904                      } else {
00905                             $testfile = realpath("{$dir}/{$name}");
00906                             $test_files[] = $testfile;
00907                      }
00908               }
00909        }
00910 
00911        closedir($o);
00912 }
00913 
00914 function test_name($name)
00915 {
00916        if (is_array($name)) {
00917               return $name[0] . ':' . $name[1];
00918        } else {
00919               return $name;
00920        }
00921 }
00922 
00923 function test_sort($a, $b)
00924 {
00925        global $cwd;
00926 
00927        $a = test_name($a);
00928        $b = test_name($b);
00929 
00930        $ta = strpos($a, "{$cwd}/tests") === 0 ? 1 + (strpos($a, "{$cwd}/tests/run-test") === 0 ? 1 : 0) : 0;
00931        $tb = strpos($b, "{$cwd}/tests") === 0 ? 1 + (strpos($b, "{$cwd}/tests/run-test") === 0 ? 1 : 0) : 0;
00932 
00933        if ($ta == $tb) {
00934               return strcmp($a, $b);
00935        } else {
00936               return $tb - $ta;
00937        }
00938 }
00939 
00940 $test_files = array_unique($test_files);
00941 usort($test_files, "test_sort");
00942 
00943 $start_time = time();
00944 show_start($start_time);
00945 
00946 $test_cnt = count($test_files);
00947 $test_idx = 0;
00948 run_all_tests($test_files, $environment);
00949 $end_time = time();
00950 
00951 if ($failed_tests_file) {
00952        fclose($failed_tests_file);
00953 }
00954 
00955 // Summarize results
00956 
00957 if (0 == count($test_results)) {
00958        echo "No tests were run.\n";
00959        return;
00960 }
00961 
00962 compute_summary();
00963 
00964 show_end($end_time);
00965 show_summary();
00966 
00967 if ($html_output) {
00968        fclose($html_file);
00969 }
00970 
00971 save_or_mail_results();
00972 
00973 if ($JUNIT) {
00974        save_junit_xml();
00975 }
00976 
00977 if (getenv('REPORT_EXIT_STATUS') == 1 and $sum_results['FAILED']) {
00978        exit(1);
00979 }
00980 exit(0);
00981 
00982 //
00983 // Send Email to QA Team
00984 //
00985 
00986 function mail_qa_team($data, $compression, $status = false)
00987 {
00988        $url_bits = parse_url(QA_SUBMISSION_PAGE);
00989 
00990     if (($proxy = getenv('http_proxy'))) {
00991         $proxy = parse_url($proxy);
00992         $path = $url_bits['host'].$url_bits['path'];
00993         $host = $proxy['host'];
00994         if (empty($proxy['port'])) {
00995             $proxy['port'] = 80;
00996         }
00997         $port = $proxy['port'];
00998     } else {
00999         $path = $url_bits['path'];
01000         $host = $url_bits['host'];
01001         $port = empty($url_bits['port']) ? 80 : $port = $url_bits['port'];
01002     }
01003 
01004        $data = "php_test_data=" . urlencode(base64_encode(str_replace("\00", '[0x0]', $data)));
01005        $data_length = strlen($data);
01006 
01007        $fs = fsockopen($host, $port, $errno, $errstr, 10);
01008 
01009        if (!$fs) {
01010               return false;
01011        }
01012 
01013        $php_version = urlencode(TESTED_PHP_VERSION);
01014 
01015        echo "\nPosting to ". QA_SUBMISSION_PAGE . "\n";
01016        fwrite($fs, "POST " . $path . "?status=$status&version=$php_version HTTP/1.1\r\n");
01017        fwrite($fs, "Host: " . $host . "\r\n");
01018        fwrite($fs, "User-Agent: QA Browser 0.1\r\n");
01019        fwrite($fs, "Content-Type: application/x-www-form-urlencoded\r\n");
01020        fwrite($fs, "Content-Length: " . $data_length . "\r\n\r\n");
01021        fwrite($fs, $data);
01022        fwrite($fs, "\r\n\r\n");
01023        fclose($fs);
01024 
01025        return 1;
01026 }
01027 
01028 
01029 //
01030 //  Write the given text to a temporary file, and return the filename.
01031 //
01032 
01033 function save_text($filename, $text, $filename_copy = null)
01034 {
01035        global $DETAILED;
01036 
01037        if ($filename_copy && $filename_copy != $filename) {
01038               if (file_put_contents($filename_copy, $text, FILE_BINARY) === false) {
01039                      error("Cannot open file '" . $filename_copy . "' (save_text)");
01040               }
01041        }
01042 
01043        if (file_put_contents($filename, $text, FILE_BINARY) === false) {
01044               error("Cannot open file '" . $filename . "' (save_text)");
01045        }
01046 
01047        if (1 < $DETAILED) echo "
01048 FILE $filename {{{
01049 $text
01050 }}}
01051 ";
01052 }
01053 
01054 //
01055 //  Write an error in a format recognizable to Emacs or MSVC.
01056 //
01057 
01058 function error_report($testname, $logname, $tested)
01059 {
01060        $testname = realpath($testname);
01061        $logname  = realpath($logname);
01062 
01063        switch (strtoupper(getenv('TEST_PHP_ERROR_STYLE'))) {
01064               case 'MSVC':
01065                      echo $testname . "(1) : $tested\n";
01066                      echo $logname . "(1) :  $tested\n";
01067                      break;
01068               case 'EMACS':
01069                      echo $testname . ":1: $tested\n";
01070                      echo $logname . ":1:  $tested\n";
01071                      break;
01072        }
01073 }
01074 
01075 function system_with_timeout($commandline, $env = null, $stdin = null)
01076 {
01077        global $leak_check, $cwd;
01078 
01079        $data = '';
01080 
01081        $bin_env = array();
01082        foreach((array)$env as $key => $value) {
01083               $bin_env[$key] = $value;
01084        }
01085 
01086        $proc = proc_open($commandline, array(
01087               0 => array('pipe', 'r'),
01088               1 => array('pipe', 'w'),
01089               2 => array('pipe', 'w')
01090               ), $pipes, $cwd, $bin_env, array('suppress_errors' => true, 'binary_pipes' => true));
01091 
01092        if (!$proc) {
01093               return false;
01094        }
01095 
01096        if (!is_null($stdin)) {
01097               fwrite($pipes[0], $stdin);
01098        }
01099        fclose($pipes[0]);
01100 
01101        $timeout = $leak_check ? 300 : (isset($env['TEST_TIMEOUT']) ? $env['TEST_TIMEOUT'] : 60);
01102 
01103        while (true) {
01104               /* hide errors from interrupted syscalls */
01105               $r = $pipes;
01106               $w = null;
01107               $e = null;
01108 
01109               $n = @stream_select($r, $w, $e, $timeout);
01110 
01111               if ($n === false) {
01112                      break;
01113               } else if ($n === 0) {
01114                      /* timed out */
01115                      $data .= "\n ** ERROR: process timed out **\n";
01116                      proc_terminate($proc, 9);
01117                      return $data;
01118               } else if ($n > 0) {
01119                      $line = fread($pipes[1], 8192);
01120                      if (strlen($line) == 0) {
01121                             /* EOF */
01122                             break;
01123                      }
01124                      $data .= $line;
01125               }
01126        }
01127 
01128        $stat = proc_get_status($proc);
01129 
01130        if ($stat['signaled']) {
01131               $data .= "\nTermsig=" . $stat['stopsig'];
01132        }
01133 
01134        $code = proc_close($proc);
01135        return $data;
01136 }
01137 
01138 function run_all_tests($test_files, $env, $redir_tested = null)
01139 {
01140        global $test_results, $failed_tests_file, $php, $test_cnt, $test_idx;
01141 
01142        foreach($test_files as $name) {
01143 
01144               if (is_array($name)) {
01145                      $index = "# $name[1]: $name[0]";
01146 
01147                      if ($redir_tested) {
01148                             $name = $name[0];
01149                      }
01150               } else if ($redir_tested) {
01151                      $index = "# $redir_tested: $name";
01152               } else {
01153                      $index = $name;
01154               }
01155               $test_idx++;
01156               $result = run_test($php, $name, $env);
01157 
01158               if (!is_array($name) && $result != 'REDIR') {
01159                      $test_results[$index] = $result;
01160                      if ($failed_tests_file && ($result == 'XFAILED' || $result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED')) {
01161                             fwrite($failed_tests_file, "$index\n");
01162                      }
01163               }
01164        }
01165 }
01166 
01167 //
01168 //  Show file or result block
01169 //
01170 function show_file_block($file, $block, $section = null)
01171 {
01172        global $cfg;
01173 
01174        if ($cfg['show'][$file]) {
01175 
01176               if (is_null($section)) {
01177                      $section = strtoupper($file);
01178               }
01179 
01180               echo "\n========" . $section . "========\n";
01181               echo rtrim($block);
01182               echo "\n========DONE========\n";
01183        }
01184 }
01185 
01186 //
01187 //  Run an individual test case.
01188 //
01189 function run_test($php, $file, $env)
01190 {
01191        global $log_format, $info_params, $ini_overwrites, $cwd, $PHP_FAILED_TESTS;
01192        global $pass_options, $DETAILED, $IN_REDIRECT, $test_cnt, $test_idx;
01193        global $leak_check, $temp_source, $temp_target, $cfg, $environment;
01194        global $no_clean;
01195        global $valgrind_version;
01196        global $JUNIT;
01197        $temp_filenames = null;
01198        $org_file = $file;
01199 
01200        if (isset($env['TEST_PHP_CGI_EXECUTABLE'])) {
01201               $php_cgi = $env['TEST_PHP_CGI_EXECUTABLE'];
01202        }
01203 
01204        if (is_array($file)) {
01205               $file = $file[0];
01206        }
01207 
01208        if ($DETAILED) echo "
01209 =================
01210 TEST $file
01211 ";
01212 
01213        // Load the sections of the test file.
01214        $section_text = array('TEST' => '');
01215 
01216        $fp = fopen($file, "rb") or error("Cannot open test file: $file");
01217 
01218        $borked = false;
01219        $bork_info = '';
01220 
01221        if (!feof($fp)) {
01222               $line = fgets($fp);
01223 
01224               if ($line === false) {
01225                      $bork_info = "cannot read test";
01226                      $borked = true;
01227               }
01228        } else {
01229               $bork_info = "empty test [$file]";
01230               $borked = true;
01231        }
01232        if (!$borked && strncmp('--TEST--', $line, 8)) {
01233               $bork_info = "tests must start with --TEST-- [$file]";
01234               $borked = true;
01235        }
01236 
01237        $section = 'TEST';
01238        $secfile = false;
01239        $secdone = false;
01240 
01241        while (!feof($fp)) {
01242               $line = fgets($fp);
01243 
01244               if ($line === false) {
01245                      break;
01246               }
01247 
01248               // Match the beginning of a section.
01249               if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
01250                      $section = $r[1];
01251                      settype($section, 'string');
01252 
01253                      if (isset($section_text[$section])) {
01254                             $bork_info = "duplicated $section section";
01255                             $borked    = true;
01256                      }
01257 
01258                      $section_text[$section] = '';
01259                      $secfile = $section == 'FILE' || $section == 'FILEEOF' || $section == 'FILE_EXTERNAL';
01260                      $secdone = false;
01261                      continue;
01262               }
01263 
01264               // Add to the section text.
01265               if (!$secdone) {
01266                      $section_text[$section] .= $line;
01267               }
01268 
01269               // End of actual test?
01270               if ($secfile && preg_match('/^===DONE===\s*$/', $line)) {
01271                      $secdone = true;
01272               }
01273        }
01274 
01275        // the redirect section allows a set of tests to be reused outside of
01276        // a given test dir
01277        if (!$borked) {
01278               if (@count($section_text['REDIRECTTEST']) == 1) {
01279 
01280                      if ($IN_REDIRECT) {
01281                             $borked = true;
01282                             $bork_info = "Can't redirect a test from within a redirected test";
01283                      } else {
01284                             $borked = false;
01285                      }
01286 
01287               } else {
01288 
01289                      if (@count($section_text['FILE']) + @count($section_text['FILEEOF']) + @count($section_text['FILE_EXTERNAL']) != 1) {
01290                             $bork_info = "missing section --FILE--";
01291                             $borked = true;
01292                      }
01293 
01294                      if (@count($section_text['FILEEOF']) == 1) {
01295                             $section_text['FILE'] = preg_replace("/[\r\n]+$/", '', $section_text['FILEEOF']);
01296                             unset($section_text['FILEEOF']);
01297                      }
01298 
01299                      if (@count($section_text['FILE_EXTERNAL']) == 1) {
01300                             // don't allow tests to retrieve files from anywhere but this subdirectory
01301                             $section_text['FILE_EXTERNAL'] = dirname($file) . '/' . trim(str_replace('..', '', $section_text['FILE_EXTERNAL']));
01302 
01303                             if (file_exists($section_text['FILE_EXTERNAL'])) {
01304                                    $section_text['FILE'] = file_get_contents($section_text['FILE_EXTERNAL'], FILE_BINARY);
01305                                    unset($section_text['FILE_EXTERNAL']);
01306                             } else {
01307                                    $bork_info = "could not load --FILE_EXTERNAL-- " . dirname($file) . '/' . trim($section_text['FILE_EXTERNAL']);
01308                                    $borked = true;
01309                             }
01310                      }
01311 
01312                      if ((@count($section_text['EXPECT']) + @count($section_text['EXPECTF']) + @count($section_text['EXPECTREGEX'])) != 1) {
01313                             $bork_info = "missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--";
01314                             $borked = true;
01315                      }
01316               }
01317        }
01318        fclose($fp);
01319 
01320        $shortname = str_replace($cwd . '/', '', $file);
01321        $tested_file = $shortname;
01322 
01323        if ($borked) {
01324               show_result("BORK", $bork_info, $tested_file);
01325               $PHP_FAILED_TESTS['BORKED'][] = array (
01326                                                         'name'      => $file,
01327                                                         'test_name' => '',
01328                                                         'output'    => '',
01329                                                         'diff'      => '',
01330                                                         'info'      => "$bork_info [$file]",
01331               );
01332               
01333               if ($JUNIT) {
01334                      $JUNIT['test_total']++;
01335                      $JUNIT['test_error']++;
01336                      $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested_file, ENT_QUOTES).'" time="0">'."\n";
01337                      $JUNIT['result_xml'] .= '<error type="BORKED" message="'.$bork_info.'" />'."\n";
01338                      $JUNIT['result_xml'] .= '</testcase>'."\n";
01339               }
01340               return 'BORKED';
01341        }
01342 
01343        $tested = trim($section_text['TEST']);
01344 
01345        /* For GET/POST tests, check if cgi sapi is available and if it is, use it. */
01346        if (!empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) {
01347               if (isset($php_cgi)) {
01348                      $old_php = $php;
01349                      $php = $php_cgi . ' -C ';
01350               } else if (!strncasecmp(PHP_OS, "win", 3) && file_exists(dirname($php) . "/php-cgi.exe")) {
01351                      $old_php = $php;
01352                      $php = realpath(dirname($php) . "/php-cgi.exe") . ' -C ';
01353               } else {
01354                      if (file_exists(dirname($php) . "/../../sapi/cgi/php-cgi")) {
01355                             $old_php = $php;
01356                             $php = realpath(dirname($php) . "/../../sapi/cgi/php-cgi") . ' -C ';
01357                      } else if (file_exists("./sapi/cgi/php-cgi")) {
01358                             $old_php = $php;
01359                             $php = realpath("./sapi/cgi/php-cgi") . ' -C ';
01360                      } else {
01361                             show_result('SKIP', $tested, $tested_file, "reason: CGI not available");
01362                             if ($JUNIT) {
01363                                    $JUNIT['test_total']++;
01364                                    $JUNIT['test_skip']++;
01365                                    $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="0">'."\n";
01366                                    $JUNIT['result_xml'] .= '<skipped>CGI not available</skipped>'."\n";
01367                                    $JUNIT['result_xml'] .= '</testcase>'."\n";
01368                             }
01369                             return 'SKIPPED';
01370                      }
01371               }
01372        }
01373 
01374        show_test($test_idx, $shortname);
01375 
01376        if (is_array($IN_REDIRECT)) {
01377               $temp_dir = $test_dir = $IN_REDIRECT['dir'];
01378        } else {
01379               $temp_dir = $test_dir = realpath(dirname($file));
01380        }
01381 
01382        if ($temp_source && $temp_target) {
01383               $temp_dir = str_replace($temp_source, $temp_target, $temp_dir);
01384        }
01385 
01386        $main_file_name = basename($file,'phpt');
01387 
01388        $diff_filename     = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'diff';
01389        $log_filename      = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'log';
01390        $exp_filename      = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'exp';
01391        $output_filename   = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'out';
01392        $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'mem';
01393        $sh_filename       = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'sh';
01394        $temp_file         = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php';
01395        $test_file         = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'php';
01396        $temp_skipif       = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php';
01397        $test_skipif       = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'skip.php';
01398        $temp_clean        = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php';
01399        $test_clean        = $test_dir . DIRECTORY_SEPARATOR . $main_file_name . 'clean.php';
01400        $tmp_post          = $temp_dir . DIRECTORY_SEPARATOR . uniqid('/phpt.');
01401        $tmp_relative_file = str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', $test_file) . 't';
01402 
01403        if ($temp_source && $temp_target) {
01404               $temp_skipif  .= 's';
01405               $temp_file    .= 's';
01406               $temp_clean   .= 's';
01407               $copy_file     = $temp_dir . DIRECTORY_SEPARATOR . basename(is_array($file) ? $file[1] : $file) . '.phps';
01408 
01409               if (!is_dir(dirname($copy_file))) {
01410                      mkdir(dirname($copy_file), 0777, true) or error("Cannot create output directory - " . dirname($copy_file));
01411               }
01412 
01413               if (isset($section_text['FILE'])) {
01414                      save_text($copy_file, $section_text['FILE']);
01415               }
01416 
01417               $temp_filenames = array(
01418                      'file' => $copy_file,
01419                      'diff' => $diff_filename,
01420                      'log'  => $log_filename,
01421                      'exp'  => $exp_filename,
01422                      'out'  => $output_filename,
01423                      'mem'  => $memcheck_filename,
01424                      'sh'   => $sh_filename,
01425                      'php'  => $temp_file,
01426                      'skip' => $temp_skipif,
01427                      'clean'=> $temp_clean);
01428        }
01429 
01430        if (is_array($IN_REDIRECT)) {
01431               $tested = $IN_REDIRECT['prefix'] . ' ' . trim($section_text['TEST']);
01432               $tested_file = $tmp_relative_file;
01433        }
01434 
01435        // unlink old test results
01436        @unlink($diff_filename);
01437        @unlink($log_filename);
01438        @unlink($exp_filename);
01439        @unlink($output_filename);
01440        @unlink($memcheck_filename);
01441        @unlink($sh_filename);
01442        @unlink($temp_file);
01443        @unlink($test_file);
01444        @unlink($temp_skipif);
01445        @unlink($test_skipif);
01446        @unlink($tmp_post);
01447        @unlink($temp_clean);
01448        @unlink($test_clean);
01449 
01450        // Reset environment from any previous test.
01451        $env['REDIRECT_STATUS'] = '';
01452        $env['QUERY_STRING']    = '';
01453        $env['PATH_TRANSLATED'] = '';
01454        $env['SCRIPT_FILENAME'] = '';
01455        $env['REQUEST_METHOD']  = '';
01456        $env['CONTENT_TYPE']    = '';
01457        $env['CONTENT_LENGTH']  = '';
01458        $env['TZ']              = '';
01459 
01460        if (!empty($section_text['ENV'])) {
01461 
01462               foreach(explode("\n", trim($section_text['ENV'])) as $e) {
01463                      $e = explode('=', trim($e), 2);
01464 
01465                      if (!empty($e[0]) && isset($e[1])) {
01466                             $env[$e[0]] = $e[1];
01467                      }
01468               }
01469        }
01470 
01471        // Default ini settings
01472        $ini_settings = array();
01473        // additional ini overwrites
01474        //$ini_overwrites[] = 'setting=value';
01475        settings2array($ini_overwrites, $ini_settings);
01476 
01477        // Any special ini settings
01478        // these may overwrite the test defaults...
01479        if (array_key_exists('INI', $section_text)) {
01480               if (strpos($section_text['INI'], '{PWD}') !== false) {
01481                      $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
01482               }
01483               settings2array(preg_split( "/[\n\r]+/", $section_text['INI']), $ini_settings);
01484        }
01485 
01486        // Additional required extensions
01487        if (array_key_exists('EXTENSIONS', $section_text)) {
01488               $ext_dir=`$php -r 'echo ini_get("extension_dir");'`;
01489               $extensions = preg_split("/[\n\r]+/", trim($section_text['EXTENSIONS']));
01490               $loaded = explode(",", `$php -n -r 'echo join(",", get_loaded_extensions());'`);
01491               foreach ($extensions as $req_ext) {
01492                      if (!in_array($req_ext, $loaded)) {
01493                             $ini_settings['extension'][] = $ext_dir . DIRECTORY_SEPARATOR . $req_ext . '.' . PHP_SHLIB_SUFFIX;
01494                      }
01495               }
01496        }
01497 
01498        settings2params($ini_settings);
01499 
01500        // Check if test should be skipped.
01501        $info = '';
01502        $warn = false;
01503 
01504        if (array_key_exists('SKIPIF', $section_text)) {
01505 
01506               if (trim($section_text['SKIPIF'])) {
01507                      show_file_block('skip', $section_text['SKIPIF']);
01508                      save_text($test_skipif, $section_text['SKIPIF'], $temp_skipif);
01509                      $extra = substr(PHP_OS, 0, 3) !== "WIN" ?
01510                             "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;": "";
01511 
01512                      if ($leak_check) {
01513                             $env['USE_ZEND_ALLOC'] = '0';
01514                      } else {
01515                             $env['USE_ZEND_ALLOC'] = '1';
01516                      }
01517 
01518                      if ($JUNIT) {
01519                             $test_started_at     = microtime(true);
01520                      }
01521                      $output = system_with_timeout("$extra $php $pass_options -q $ini_settings -d display_errors=0 $test_skipif", $env);
01522                      if ($JUNIT) {
01523                             $test_finished_at   = microtime(true);
01524                             $test_execution_time= number_format($test_finished_at-$test_started_at, 2);
01525                      }
01526 
01527                      if (!$cfg['keep']['skip']) {
01528                             @unlink($test_skipif);
01529                      }
01530 
01531                      if (!strncasecmp('skip', ltrim($output), 4)) {
01532 
01533                             if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
01534                                    show_result('SKIP', $tested, $tested_file, "reason: $m[1]", $temp_filenames);
01535                             } else {
01536                                    show_result('SKIP', $tested, $tested_file, '', $temp_filenames);
01537                             }
01538 
01539                             if (isset($old_php)) {
01540                                    $php = $old_php;
01541                             }
01542 
01543                             if (!$cfg['keep']['skip']) {
01544                                    @unlink($test_skipif);
01545                             }
01546 
01547                             if ($JUNIT) {
01548                                    $JUNIT['test_total']++;
01549                                    $JUNIT['test_skip']++;
01550                                    $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="'.$test_execution_time.'">'."\n";
01551                                    $JUNIT['result_xml'] .= '<skipped><![CDATA['."\n".$m[1]."\n".']]></skipped>'."\n";
01552                                    $JUNIT['result_xml'] .= '</testcase>'."\n";
01553                             }
01554                             return 'SKIPPED';
01555                      }
01556 
01557                      if (!strncasecmp('info', ltrim($output), 4)) {
01558                             if (preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
01559                                    $info = " (info: $m[1])";
01560                             }
01561                      }
01562 
01563                      if (!strncasecmp('warn', ltrim($output), 4)) {
01564                             if (preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
01565                                    $warn = true; /* only if there is a reason */
01566                                    $info = " (warn: $m[1])";
01567                             }
01568                      }
01569               }
01570        }
01571 
01572        if (@count($section_text['REDIRECTTEST']) == 1) {
01573               $test_files = array();
01574 
01575               $IN_REDIRECT = eval($section_text['REDIRECTTEST']);
01576               $IN_REDIRECT['via'] = "via [$shortname]\n\t";
01577               $IN_REDIRECT['dir'] = realpath(dirname($file));
01578               $IN_REDIRECT['prefix'] = trim($section_text['TEST']);
01579 
01580               if (count($IN_REDIRECT['TESTS']) == 1) {
01581 
01582                      if (is_array($org_file)) {
01583                             $test_files[] = $org_file[1];
01584                      } else {
01585                             $GLOBALS['test_files'] = $test_files;
01586                             find_files($IN_REDIRECT['TESTS']);
01587 
01588                             foreach($GLOBALS['test_files'] as $f) {
01589                                    $test_files[] = array($f, $file);
01590                             }
01591                      }
01592                      $test_cnt += @count($test_files) - 1;
01593                      $test_idx--;
01594 
01595                      show_redirect_start($IN_REDIRECT['TESTS'], $tested, $tested_file);
01596 
01597                      // set up environment
01598                      $redirenv = array_merge($environment, $IN_REDIRECT['ENV']);
01599                      $redirenv['REDIR_TEST_DIR'] = realpath($IN_REDIRECT['TESTS']) . DIRECTORY_SEPARATOR;
01600 
01601                      usort($test_files, "test_sort");
01602                      run_all_tests($test_files, $redirenv, $tested);
01603 
01604                      show_redirect_ends($IN_REDIRECT['TESTS'], $tested, $tested_file);
01605 
01606                      // a redirected test never fails
01607                      $IN_REDIRECT = false;
01608                      if ($JUNIT) {
01609                             $JUNIT['test_total']++;
01610                             $JUNIT['test_pass']++;
01611                             $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="'.$test_execution_time.'">'."\n";
01612                             $JUNIT['result_xml'] .= '</testcase>'."\n";
01613                      }
01614                      return 'REDIR';
01615 
01616               } else {
01617 
01618                      $bork_info = "Redirect info must contain exactly one TEST string to be used as redirect directory.";
01619                      show_result("BORK", $bork_info, '', $temp_filenames);
01620                      $PHP_FAILED_TESTS['BORKED'][] = array (
01621                                                                'name' => $file,
01622                                                                'test_name' => '',
01623                                                                'output' => '',
01624                                                                'diff'   => '',
01625                                                                'info'   => "$bork_info [$file]",
01626                      );
01627               }
01628        }
01629 
01630        if (is_array($org_file) || @count($section_text['REDIRECTTEST']) == 1) {
01631 
01632               if (is_array($org_file)) {
01633                      $file = $org_file[0];
01634               }
01635 
01636               $bork_info = "Redirected test did not contain redirection info";
01637               show_result("BORK", $bork_info, '', $temp_filenames);
01638               $PHP_FAILED_TESTS['BORKED'][] = array (
01639                                                         'name' => $file,
01640                                                         'test_name' => '',
01641                                                         'output' => '',
01642                                                         'diff'   => '',
01643                                                         'info'   => "$bork_info [$file]",
01644               );
01645               if ($JUNIT) {
01646                      $JUNIT['test_total']++;
01647                      $JUNIT['test_error']++;
01648                      $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="'.$test_execution_time.'">'."\n";
01649                      $JUNIT['result_xml'] .= '<error type="BORKED" message="'.$bork_info.'" />'."\n";
01650                      $JUNIT['result_xml'] .= '</testcase>'."\n";
01651               }
01652               return 'BORKED';
01653        }
01654 
01655        // We've satisfied the preconditions - run the test!
01656        show_file_block('php', $section_text['FILE'], 'TEST');
01657        save_text($test_file, $section_text['FILE'], $temp_file);
01658 
01659        if (array_key_exists('GET', $section_text)) {
01660               $query_string = trim($section_text['GET']);
01661        } else {
01662               $query_string = '';
01663        }
01664 
01665        $env['REDIRECT_STATUS'] = '1';
01666        $env['QUERY_STRING']    = $query_string;
01667        $env['PATH_TRANSLATED'] = $test_file;
01668        $env['SCRIPT_FILENAME'] = $test_file;
01669 
01670        if (array_key_exists('COOKIE', $section_text)) {
01671               $env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
01672        } else {
01673               $env['HTTP_COOKIE'] = '';
01674        }
01675 
01676        $args = isset($section_text['ARGS']) ? ' -- ' . $section_text['ARGS'] : '';
01677 
01678        if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) {
01679 
01680               $post = trim($section_text['POST_RAW']);
01681               $raw_lines = explode("\n", $post);
01682 
01683               $request = '';
01684               $started = false;
01685 
01686               foreach ($raw_lines as $line) {
01687 
01688                      if (empty($env['CONTENT_TYPE']) && preg_match('/^Content-Type:(.*)/i', $line, $res)) {
01689                             $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1]));
01690                             continue;
01691                      }
01692 
01693                      if ($started) {
01694                             $request .= "\n";
01695                      }
01696 
01697                      $started = true;
01698                      $request .= $line;
01699               }
01700 
01701               $env['CONTENT_LENGTH'] = strlen($request);
01702               $env['REQUEST_METHOD'] = 'POST';
01703 
01704               if (empty($request)) {
01705                      if ($JUNIT) {
01706                             $JUNIT['test_total']++;
01707                             $JUNIT['test_error']++;
01708                             $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="'.$test_execution_time.'">'."\n";
01709                             $JUNIT['result_xml'] .= '<error type="BORKED" message="empty $request" />'."\n";
01710                             $JUNIT['result_xml'] .= '</testcase>'."\n";
01711                      }
01712                      return 'BORKED';
01713               }
01714 
01715               save_text($tmp_post, $request);
01716               $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < $tmp_post";
01717 
01718        } else if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) {
01719 
01720               $post = trim($section_text['POST']);
01721 
01722               if (array_key_exists('GZIP_POST', $section_text) && function_exists('gzencode')) {
01723                      $post = gzencode($post, 9, FORCE_GZIP);
01724                      $env['HTTP_CONTENT_ENCODING'] = 'gzip';
01725               } else if (array_key_exists('DEFLATE_POST', $section_text) && function_exists('gzcompress')) {
01726                      $post = gzcompress($post, 9);
01727                      $env['HTTP_CONTENT_ENCODING'] = 'deflate';
01728               }
01729 
01730               save_text($tmp_post, $post);
01731               $content_length = strlen($post);
01732 
01733               $env['REQUEST_METHOD'] = 'POST';
01734               $env['CONTENT_TYPE']   = 'application/x-www-form-urlencoded';
01735               $env['CONTENT_LENGTH'] = $content_length;
01736 
01737               $cmd = "$php $pass_options $ini_settings -f \"$test_file\" 2>&1 < $tmp_post";
01738 
01739        } else {
01740 
01741               $env['REQUEST_METHOD'] = 'GET';
01742               $env['CONTENT_TYPE']   = '';
01743               $env['CONTENT_LENGTH'] = '';
01744 
01745               $cmd = "$php $pass_options $ini_settings -f \"$test_file\" $args 2>&1";
01746        }
01747 
01748        if ($leak_check) {
01749               $env['USE_ZEND_ALLOC'] = '0';
01750 
01751               if ($valgrind_version >= 330) {
01752                      /* valgrind 3.3.0+ doesn't have --log-file-exactly option */
01753                      $cmd = "valgrind -q --tool=memcheck --trace-children=yes --log-file=$memcheck_filename $cmd";
01754               } else {
01755                      $cmd = "valgrind -q --tool=memcheck --trace-children=yes --log-file-exactly=$memcheck_filename $cmd";
01756               }
01757 
01758        } else {
01759               $env['USE_ZEND_ALLOC'] = '1';
01760        }
01761 
01762        if ($DETAILED) echo "
01763 CONTENT_LENGTH  = " . $env['CONTENT_LENGTH'] . "
01764 CONTENT_TYPE    = " . $env['CONTENT_TYPE'] . "
01765 PATH_TRANSLATED = " . $env['PATH_TRANSLATED'] . "
01766 QUERY_STRING    = " . $env['QUERY_STRING'] . "
01767 REDIRECT_STATUS = " . $env['REDIRECT_STATUS'] . "
01768 REQUEST_METHOD  = " . $env['REQUEST_METHOD'] . "
01769 SCRIPT_FILENAME = " . $env['SCRIPT_FILENAME'] . "
01770 HTTP_COOKIE     = " . $env['HTTP_COOKIE'] . "
01771 COMMAND $cmd
01772 ";
01773 
01774        if ($JUNIT) {
01775               $test_started_at    = microtime(true);
01776        }
01777        $out = system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null);
01778        if ($JUNIT) {
01779               $test_finished_at   = microtime(true);
01780               $test_execution_time= number_format($test_finished_at-$test_started_at, 2);
01781        }
01782 
01783        if (array_key_exists('CLEAN', $section_text) && (!$no_clean || $cfg['keep']['clean'])) {
01784 
01785               if (trim($section_text['CLEAN'])) {
01786                      show_file_block('clean', $section_text['CLEAN']);
01787                      save_text($test_clean, trim($section_text['CLEAN']), $temp_clean);
01788 
01789                      if (!$no_clean) {
01790                             $clean_params = array();
01791                             settings2array($ini_overwrites, $clean_params);
01792                             settings2params($clean_params);
01793                             $extra = substr(PHP_OS, 0, 3) !== "WIN" ?
01794                                    "unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;": "";
01795                             system_with_timeout("$extra $php $pass_options -q $clean_params $test_clean", $env);
01796                      }
01797 
01798                      if (!$cfg['keep']['clean']) {
01799                             @unlink($test_clean);
01800                      }
01801               }
01802        }
01803 
01804        @unlink($tmp_post);
01805 
01806        $leaked = false;
01807        $passed = false;
01808 
01809        if ($leak_check) { // leak check
01810               $leaked = filesize($memcheck_filename) > 0;
01811 
01812               if (!$leaked) {
01813                      @unlink($memcheck_filename);
01814               }
01815        }
01816 
01817        // Does the output match what is expected?
01818        $output = preg_replace("/\r\n/", "\n", trim($out));
01819 
01820        /* when using CGI, strip the headers from the output */
01821        $headers = "";
01822 
01823        if (isset($old_php) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) {
01824               $output = trim($match[2]);
01825               $rh = preg_split("/[\n\r]+/", $match[1]);
01826               $headers = array();
01827 
01828               foreach ($rh as $line) {
01829                      if (strpos($line, ':') !== false) {
01830                             $line = explode(':', $line, 2);
01831                             $headers[trim($line[0])] = trim($line[1]);
01832                      }
01833               }
01834        }
01835 
01836        $failed_headers = false;
01837 
01838        if (isset($section_text['EXPECTHEADERS'])) {
01839               $want = array();
01840               $wanted_headers = array();
01841               $lines = preg_split("/[\n\r]+/", $section_text['EXPECTHEADERS']);
01842 
01843               foreach($lines as $line) {
01844                      if (strpos($line, ':') !== false) {
01845                             $line = explode(':', $line, 2);
01846                             $want[trim($line[0])] = trim($line[1]);
01847                             $wanted_headers[] = trim($line[0]) . ': ' . trim($line[1]);
01848                      }
01849               }
01850 
01851               $org_headers = $headers;
01852               $headers = array();
01853               $output_headers = array();
01854 
01855               foreach($want as $k => $v) {
01856 
01857                      if (isset($org_headers[$k])) {
01858                             $headers = $org_headers[$k];
01859                             $output_headers[] = $k . ': ' . $org_headers[$k];
01860                      }
01861 
01862                      if (!isset($org_headers[$k]) || $org_headers[$k] != $v) {
01863                             $failed_headers = true;
01864                      }
01865               }
01866 
01867               ksort($wanted_headers);
01868               $wanted_headers = join("\n", $wanted_headers);
01869               ksort($output_headers);
01870               $output_headers = join("\n", $output_headers);
01871        }
01872 
01873        show_file_block('out', $output);
01874 
01875        if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
01876 
01877               if (isset($section_text['EXPECTF'])) {
01878                      $wanted = trim($section_text['EXPECTF']);
01879               } else {
01880                      $wanted = trim($section_text['EXPECTREGEX']);
01881               }
01882 
01883               show_file_block('exp', $wanted);
01884               $wanted_re = preg_replace('/\r\n/', "\n", $wanted);
01885 
01886               if (isset($section_text['EXPECTF'])) {
01887 
01888                      // do preg_quote, but miss out any %r delimited sections
01889                      $temp = "";
01890                      $r = "%r";
01891                      $startOffset = 0;
01892                      $length = strlen($wanted_re);
01893                      while($startOffset < $length) {
01894                             $start = strpos($wanted_re, $r, $startOffset);
01895                             if ($start !== false) {
01896                                    // we have found a start tag
01897                                    $end = strpos($wanted_re, $r, $start+2);
01898                                    if ($end === false) {
01899                                           // unbalanced tag, ignore it.
01900                                           $end = $start = $length;
01901                                    }
01902                             } else {
01903                                    // no more %r sections
01904                                    $start = $end = $length;
01905                             }
01906                             // quote a non re portion of the string
01907                             $temp = $temp . preg_quote(substr($wanted_re, $startOffset, ($start - $startOffset)),  '/');
01908                             // add the re unquoted.
01909                             if ($end > $start) {
01910                                    $temp = $temp . '(' . substr($wanted_re, $start+2, ($end - $start-2)). ')';
01911                             }
01912                             $startOffset = $end + 2;
01913                      }
01914                      $wanted_re = $temp;
01915 
01916                      $wanted_re = str_replace(
01917                             array('%binary_string_optional%'),
01918                             'string',
01919                             $wanted_re
01920                      );
01921                      $wanted_re = str_replace(
01922                             array('%unicode_string_optional%'),
01923                             'string',
01924                             $wanted_re
01925                      );
01926                      $wanted_re = str_replace(
01927                             array('%unicode\|string%', '%string\|unicode%'),
01928                             'string',
01929                             $wanted_re
01930                      );
01931                      $wanted_re = str_replace(
01932                             array('%u\|b%', '%b\|u%'),
01933                             '',
01934                             $wanted_re
01935                      );
01936                      // Stick to basics
01937                      $wanted_re = str_replace('%e', '\\' . DIRECTORY_SEPARATOR, $wanted_re);
01938                      $wanted_re = str_replace('%s', '[^\r\n]+', $wanted_re);
01939                      $wanted_re = str_replace('%S', '[^\r\n]*', $wanted_re);
01940                      $wanted_re = str_replace('%a', '.+', $wanted_re);
01941                      $wanted_re = str_replace('%A', '.*', $wanted_re);
01942                      $wanted_re = str_replace('%w', '\s*', $wanted_re);
01943                      $wanted_re = str_replace('%i', '[+-]?\d+', $wanted_re);
01944                      $wanted_re = str_replace('%d', '\d+', $wanted_re);
01945                      $wanted_re = str_replace('%x', '[0-9a-fA-F]+', $wanted_re);
01946                      $wanted_re = str_replace('%f', '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', $wanted_re);
01947                      $wanted_re = str_replace('%c', '.', $wanted_re);
01948                      // %f allows two points "-.0.0" but that is the best *simple* expression
01949               }
01950 /* DEBUG YOUR REGEX HERE
01951               var_dump($wanted_re);
01952               print(str_repeat('=', 80) . "\n");
01953               var_dump($output);
01954 */
01955               if (preg_match("/^$wanted_re\$/s", $output)) {
01956                      $passed = true;
01957                      if (!$cfg['keep']['php']) {
01958                             @unlink($test_file);
01959                      }
01960                      if (isset($old_php)) {
01961                             $php = $old_php;
01962                      }
01963 
01964                      if (!$leaked && !$failed_headers) {
01965                             if (isset($section_text['XFAIL'] )) {
01966                                    $warn = true;
01967                                    $info = " (warn: XFAIL section but test passes)";
01968                             }else {
01969                                    show_result("PASS", $tested, $tested_file, '', $temp_filenames);
01970                                    if ($JUNIT) {
01971                                           $JUNIT['test_total']++;
01972                                           $JUNIT['test_pass']++;
01973                                           $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="'.$test_execution_time.'">'."\n";
01974                                           $JUNIT['result_xml'] .= '</testcase>'."\n";
01975                                    }
01976                                    return 'PASSED';
01977                             }
01978                      }
01979               }
01980 
01981        } else {
01982 
01983               $wanted = trim($section_text['EXPECT']);
01984               $wanted = preg_replace('/\r\n/',"\n", $wanted);
01985               show_file_block('exp', $wanted);
01986 
01987               // compare and leave on success
01988               if (!strcmp($output, $wanted)) {
01989                      $passed = true;
01990 
01991                      if (!$cfg['keep']['php']) {
01992                             @unlink($test_file);
01993                      }
01994 
01995                      if (isset($old_php)) {
01996                             $php = $old_php;
01997                      }
01998 
01999                      if (!$leaked && !$failed_headers) {
02000                             if (isset($section_text['XFAIL'] )) {
02001                                    $warn = true;
02002                                    $info = " (warn: XFAIL section but test passes)";
02003                             }else {
02004                                    show_result("PASS", $tested, $tested_file, '', $temp_filenames);
02005                                    if ($JUNIT) {
02006                                           $JUNIT['test_total']++;
02007                                           $JUNIT['test_pass']++;
02008                                           $JUNIT['result_xml'] .= '<testcase classname="'.$shortname.'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="'.$test_execution_time.'">'."\n";
02009                                           $JUNIT['result_xml'] .= '</testcase>'."\n";
02010                                    }
02011                                    return 'PASSED';
02012                             }
02013                      }
02014               }
02015 
02016               $wanted_re = null;
02017        }
02018 
02019        // Test failed so we need to report details.
02020        if ($failed_headers) {
02021               $passed = false;
02022               $wanted = $wanted_headers . "\n--HEADERS--\n" . $wanted;
02023               $output = $output_headers . "\n--HEADERS--\n" . $output;
02024 
02025               if (isset($wanted_re)) {
02026                      $wanted_re = preg_quote($wanted_headers . "\n--HEADERS--\n", '/') . $wanted_re;
02027               }
02028        }
02029 
02030        if ($leaked) {
02031               $restype[] = 'LEAK';
02032        }
02033 
02034        if ($warn) {
02035               $restype[] = 'WARN';
02036        }
02037 
02038        if (!$passed) {
02039               if (isset($section_text['XFAIL'])) {
02040                      $restype[] = 'XFAIL';
02041                      $info = '  XFAIL REASON: ' . rtrim($section_text['XFAIL']);
02042               } else {
02043                      $restype[] = 'FAIL';
02044               }
02045        }
02046 
02047        if (!$passed) {
02048 
02049               // write .exp
02050               if (strpos($log_format, 'E') !== false && file_put_contents($exp_filename, $wanted, FILE_BINARY) === false) {
02051                      error("Cannot create expected test output - $exp_filename");
02052               }
02053 
02054               // write .out
02055               if (strpos($log_format, 'O') !== false && file_put_contents($output_filename, $output, FILE_BINARY) === false) {
02056                      error("Cannot create test output - $output_filename");
02057               }
02058 
02059               // write .diff
02060               $diff = generate_diff($wanted, $wanted_re, $output);
02061               if (is_array($IN_REDIRECT)) {
02062                      $diff = "# original source file: $shortname\n" . $diff;
02063               }
02064               show_file_block('diff', $diff);
02065               if (strpos($log_format, 'D') !== false && file_put_contents($diff_filename, $diff, FILE_BINARY) === false) {
02066                      error("Cannot create test diff - $diff_filename");
02067               }
02068 
02069               // write .sh
02070               if (strpos($log_format, 'S') !== false && file_put_contents($sh_filename, "#!/bin/sh
02071 
02072 {$cmd}
02073 ", FILE_BINARY) === false) {
02074                      error("Cannot create test shell script - $sh_filename");
02075               }
02076               chmod($sh_filename, 0755);
02077 
02078               // write .log
02079               if (strpos($log_format, 'L') !== false && file_put_contents($log_filename, "
02080 ---- EXPECTED OUTPUT
02081 $wanted
02082 ---- ACTUAL OUTPUT
02083 $output
02084 ---- FAILED
02085 ", FILE_BINARY) === false) {
02086                      error("Cannot create test log - $log_filename");
02087                      error_report($file, $log_filename, $tested);
02088               }
02089        }
02090 
02091        show_result(implode('&', $restype), $tested, $tested_file, $info, $temp_filenames);
02092 
02093        foreach ($restype as $type) {
02094               $PHP_FAILED_TESTS[$type.'ED'][] = array (
02095                      'name'      => $file,
02096                      'test_name' => (is_array($IN_REDIRECT) ? $IN_REDIRECT['via'] : '') . $tested . " [$tested_file]",
02097                      'output'    => $output_filename,
02098                      'diff'      => $diff_filename,
02099                      'info'      => $info,
02100               );
02101        }
02102 
02103        if (isset($old_php)) {
02104               $php = $old_php;
02105        }
02106        
02107        if ($JUNIT) {
02108               $JUNIT['result_xml'] .= '<testcase classname="'. str_replace($cwd . '/', '', $tested_file).'" name="'.htmlspecialchars($tested, ENT_QUOTES).'" time="'.$test_execution_time.'">'."\n";
02109               $JUNIT['test_total']++;
02110               if (in_array('XFAIL', $restype)) {
02111                      $JUNIT['test_pass']++;
02112               }
02113               elseif (in_array('FAIL', $restype)) {
02114                      $JUNIT['test_fail']++;
02115                      $JUNIT['result_xml'] .= '<failure type="'.$restype[0].'ED" message="'.$info.'"><![CDATA['."\n".preg_replace('/\e/', '<esc>', $diff)."\n".']]></failure>'."\n";
02116               }
02117               else{
02118                      $JUNIT['test_error']++;
02119                      $JUNIT['result_xml'] .= '<error type="'.$restype[0].'ED" message="'.$info.'"><![CDATA['."\n".preg_replace('/\e/', '<esc>', $diff)."\n".']]></error>'."\n";
02120               }
02121               $JUNIT['result_xml'] .= '</testcase>'."\n";
02122        }
02123 
02124        return $restype[0] . 'ED';
02125 }
02126 
02127 function comp_line($l1, $l2, $is_reg)
02128 {
02129        if ($is_reg) {
02130               return preg_match('/^'. $l1 . '$/s', $l2);
02131        } else {
02132               return !strcmp($l1, $l2);
02133        }
02134 }
02135 
02136 function count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2, $cnt1, $cnt2, $steps)
02137 {
02138        $equal = 0;
02139 
02140        while ($idx1 < $cnt1 && $idx2 < $cnt2 && comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) {
02141               $idx1++;
02142               $idx2++;
02143               $equal++;
02144               $steps--;
02145        }
02146        if (--$steps > 0) {
02147               $eq1 = 0;
02148               $st = $steps / 2;
02149 
02150               for ($ofs1 = $idx1 + 1; $ofs1 < $cnt1 && $st-- > 0; $ofs1++) {
02151                      $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $ofs1, $idx2, $cnt1, $cnt2, $st);
02152 
02153                      if ($eq > $eq1) {
02154                             $eq1 = $eq;
02155                      }
02156               }
02157 
02158               $eq2 = 0;
02159               $st = $steps;
02160 
02161               for ($ofs2 = $idx2 + 1; $ofs2 < $cnt2 && $st-- > 0; $ofs2++) {
02162                      $eq = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $ofs2, $cnt1, $cnt2, $st);
02163                      if ($eq > $eq2) {
02164                             $eq2 = $eq;
02165                      }
02166               }
02167 
02168               if ($eq1 > $eq2) {
02169                      $equal += $eq1;
02170               } else if ($eq2 > 0) {
02171                      $equal += $eq2;
02172               }
02173        }
02174 
02175        return $equal;
02176 }
02177 
02178 function generate_array_diff($ar1, $ar2, $is_reg, $w)
02179 {
02180        $idx1 = 0; $ofs1 = 0; $cnt1 = @count($ar1);
02181        $idx2 = 0; $ofs2 = 0; $cnt2 = @count($ar2);
02182        $diff = array();
02183        $old1 = array();
02184        $old2 = array();
02185 
02186        while ($idx1 < $cnt1 && $idx2 < $cnt2) {
02187 
02188               if (comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) {
02189                      $idx1++;
02190                      $idx2++;
02191                      continue;
02192               } else {
02193 
02194                      $c1 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1+1, $idx2, $cnt1, $cnt2, 10);
02195                      $c2 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2+1, $cnt1,  $cnt2, 10);
02196 
02197                      if ($c1 > $c2) {
02198                             $old1[$idx1] = sprintf("%03d- ", $idx1+1) . $w[$idx1++];
02199                             $last = 1;
02200                      } else if ($c2 > 0) {
02201                             $old2[$idx2] = sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++];
02202                             $last = 2;
02203                      } else {
02204                             $old1[$idx1] = sprintf("%03d- ", $idx1+1) . $w[$idx1++];
02205                             $old2[$idx2] = sprintf("%03d+ ", $idx2+1) . $ar2[$idx2++];
02206                      }
02207               }
02208        }
02209 
02210        reset($old1); $k1 = key($old1); $l1 = -2;
02211        reset($old2); $k2 = key($old2); $l2 = -2;
02212 
02213        while ($k1 !== null || $k2 !== null) {
02214 
02215               if ($k1 == $l1 + 1 || $k2 === null) {
02216                      $l1 = $k1;
02217                      $diff[] = current($old1);
02218                      $k1 = next($old1) ? key($old1) : null;
02219               } else if ($k2 == $l2 + 1 || $k1 === null) {
02220                      $l2 = $k2;
02221                      $diff[] = current($old2);
02222                      $k2 = next($old2) ? key($old2) : null;
02223               } else if ($k1 < $k2) {
02224                      $l1 = $k1;
02225                      $diff[] = current($old1);
02226                      $k1 = next($old1) ? key($old1) : null;
02227               } else {
02228                      $l2 = $k2;
02229                      $diff[] = current($old2);
02230                      $k2 = next($old2) ? key($old2) : null;
02231               }
02232        }
02233 
02234        while ($idx1 < $cnt1) {
02235               $diff[] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
02236        }
02237 
02238        while ($idx2 < $cnt2) {
02239               $diff[] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
02240        }
02241 
02242        return $diff;
02243 }
02244 
02245 function generate_diff($wanted, $wanted_re, $output)
02246 {
02247        $w = explode("\n", $wanted);
02248        $o = explode("\n", $output);
02249        $r = is_null($wanted_re) ? $w : explode("\n", $wanted_re);
02250        $diff = generate_array_diff($r, $o, !is_null($wanted_re), $w);
02251 
02252        return implode("\r\n", $diff);
02253 }
02254 
02255 function error($message)
02256 {
02257        echo "ERROR: {$message}\n";
02258        exit(1);
02259 }
02260 
02261 function settings2array($settings, &$ini_settings)
02262 {
02263        foreach($settings as $setting) {
02264 
02265               if (strpos($setting, '=') !== false) {
02266                      $setting = explode("=", $setting, 2);
02267                      $name = trim($setting[0]);
02268                      $value = trim($setting[1]);
02269 
02270                      if ($name == 'extension') {
02271 
02272                             if (!isset($ini_settings[$name])) {
02273                                    $ini_settings[$name] = array();
02274                             }
02275 
02276                             $ini_settings[$name][] = $value;
02277 
02278                      } else {
02279                             $ini_settings[$name] = $value;
02280                      }
02281               }
02282        }
02283 }
02284 
02285 function settings2params(&$ini_settings)
02286 {
02287        $settings = '';
02288 
02289        foreach($ini_settings as $name => $value) {
02290 
02291               if (is_array($value)) {
02292                      foreach($value as $val) {
02293                             $val = addslashes($val);
02294                             $settings .= " -d \"$name=$val\"";
02295                      }
02296               } else {
02297                      if (substr(PHP_OS, 0, 3) == "WIN" && !empty($value) && $value{0} == '"') {
02298                             $len = strlen($value);
02299 
02300                             if ($value{$len - 1} == '"') {
02301                                    $value{0} = "'";
02302                                    $value{$len - 1} = "'";
02303                             }
02304                      } else {
02305                             $value = addslashes($value);
02306                      }
02307 
02308                      $settings .= " -d \"$name=$value\"";
02309               }
02310        }
02311 
02312        $ini_settings = $settings;
02313 }
02314 
02315 function compute_summary()
02316 {
02317        global $n_total, $test_results, $ignored_by_ext, $sum_results, $percent_results;
02318 
02319        $n_total = count($test_results);
02320        $n_total += $ignored_by_ext;
02321        $sum_results = array(
02322               'PASSED'  => 0,
02323               'WARNED'  => 0,
02324               'SKIPPED' => 0,
02325               'FAILED'  => 0,
02326               'BORKED'  => 0,
02327               'LEAKED'  => 0,
02328               'XFAILED' => 0
02329        );
02330 
02331        foreach ($test_results as $v) {
02332               $sum_results[$v]++;
02333        }
02334 
02335        $sum_results['SKIPPED'] += $ignored_by_ext;
02336        $percent_results = array();
02337 
02338        while (list($v, $n) = each($sum_results)) {
02339               $percent_results[$v] = (100.0 * $n) / $n_total;
02340        }
02341 }
02342 
02343 function get_summary($show_ext_summary, $show_html)
02344 {
02345        global $exts_skipped, $exts_tested, $n_total, $sum_results, $percent_results, $end_time, $start_time, $failed_test_summary, $PHP_FAILED_TESTS, $leak_check;
02346 
02347        $x_total = $n_total - $sum_results['SKIPPED'] - $sum_results['BORKED'];
02348 
02349        if ($x_total) {
02350               $x_warned = (100.0 * $sum_results['WARNED']) / $x_total;
02351               $x_failed = (100.0 * $sum_results['FAILED']) / $x_total;
02352               $x_xfailed = (100.0 * $sum_results['XFAILED']) / $x_total;
02353               $x_leaked = (100.0 * $sum_results['LEAKED']) / $x_total;
02354               $x_passed = (100.0 * $sum_results['PASSED']) / $x_total;
02355        } else {
02356               $x_warned = $x_failed = $x_passed = $x_leaked = $x_xfailed = 0;
02357        }
02358 
02359        $summary = '';
02360 
02361        if ($show_html) {
02362               $summary .= "<pre>\n";
02363        }
02364 
02365        if ($show_ext_summary) {
02366               $summary .= '
02367 =====================================================================
02368 TEST RESULT SUMMARY
02369 ---------------------------------------------------------------------
02370 Exts skipped    : ' . sprintf('%4d', $exts_skipped) . '
02371 Exts tested     : ' . sprintf('%4d', $exts_tested) . '
02372 ---------------------------------------------------------------------
02373 ';
02374        }
02375 
02376        $summary .= '
02377 Number of tests : ' . sprintf('%4d', $n_total) . '          ' . sprintf('%8d', $x_total);
02378 
02379        if ($sum_results['BORKED']) {
02380               $summary .= '
02381 Tests borked    : ' . sprintf('%4d (%5.1f%%)', $sum_results['BORKED'], $percent_results['BORKED']) . ' --------';
02382        }
02383 
02384        $summary .= '
02385 Tests skipped   : ' . sprintf('%4d (%5.1f%%)', $sum_results['SKIPPED'], $percent_results['SKIPPED']) . ' --------
02386 Tests warned    : ' . sprintf('%4d (%5.1f%%)', $sum_results['WARNED'], $percent_results['WARNED']) . ' ' . sprintf('(%5.1f%%)', $x_warned) . '
02387 Tests failed    : ' . sprintf('%4d (%5.1f%%)', $sum_results['FAILED'], $percent_results['FAILED']) . ' ' . sprintf('(%5.1f%%)', $x_failed) . '
02388 Expected fail   : ' . sprintf('%4d (%5.1f%%)', $sum_results['XFAILED'], $percent_results['XFAILED']) . ' ' . sprintf('(%5.1f%%)', $x_xfailed);
02389 
02390        if ($leak_check) {
02391               $summary .= '
02392 Tests leaked    : ' . sprintf('%4d (%5.1f%%)', $sum_results['LEAKED'], $percent_results['LEAKED']) . ' ' . sprintf('(%5.1f%%)', $x_leaked);
02393        }
02394 
02395        $summary .= '
02396 Tests passed    : ' . sprintf('%4d (%5.1f%%)', $sum_results['PASSED'], $percent_results['PASSED']) . ' ' . sprintf('(%5.1f%%)', $x_passed) . '
02397 ---------------------------------------------------------------------
02398 Time taken      : ' . sprintf('%4d seconds', $end_time - $start_time) . '
02399 =====================================================================
02400 ';
02401        $failed_test_summary = '';
02402 
02403        if (count($PHP_FAILED_TESTS['XFAILED'])) {
02404               $failed_test_summary .= '
02405 =====================================================================
02406 EXPECTED FAILED TEST SUMMARY
02407 ---------------------------------------------------------------------
02408 ';
02409               foreach ($PHP_FAILED_TESTS['XFAILED'] as $failed_test_data) {
02410                      $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
02411               }
02412               $failed_test_summary .=  "=====================================================================\n";
02413        }
02414 
02415        if (count($PHP_FAILED_TESTS['BORKED'])) {
02416               $failed_test_summary .= '
02417 =====================================================================
02418 BORKED TEST SUMMARY
02419 ---------------------------------------------------------------------
02420 ';
02421               foreach ($PHP_FAILED_TESTS['BORKED'] as $failed_test_data) {
02422                      $failed_test_summary .= $failed_test_data['info'] . "\n";
02423               }
02424 
02425               $failed_test_summary .=  "=====================================================================\n";
02426        }
02427 
02428        if (count($PHP_FAILED_TESTS['FAILED'])) {
02429               $failed_test_summary .= '
02430 =====================================================================
02431 FAILED TEST SUMMARY
02432 ---------------------------------------------------------------------
02433 ';
02434               foreach ($PHP_FAILED_TESTS['FAILED'] as $failed_test_data) {
02435                      $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
02436               }
02437               $failed_test_summary .=  "=====================================================================\n";
02438        }
02439        if (count($PHP_FAILED_TESTS['WARNED'])) {
02440               $failed_test_summary .= '
02441 =====================================================================
02442 WARNED TEST SUMMARY
02443 ---------------------------------------------------------------------
02444 ';
02445               foreach ($PHP_FAILED_TESTS['WARNED'] as $failed_test_data) {
02446                      $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
02447               }
02448 
02449               $failed_test_summary .=  "=====================================================================\n";
02450        }
02451 
02452        if (count($PHP_FAILED_TESTS['LEAKED'])) {
02453               $failed_test_summary .= '
02454 =====================================================================
02455 LEAKED TEST SUMMARY
02456 ---------------------------------------------------------------------
02457 ';
02458               foreach ($PHP_FAILED_TESTS['LEAKED'] as $failed_test_data) {
02459                      $failed_test_summary .= $failed_test_data['test_name'] . $failed_test_data['info'] . "\n";
02460               }
02461 
02462               $failed_test_summary .=  "=====================================================================\n";
02463        }
02464 
02465        if ($failed_test_summary && !getenv('NO_PHPTEST_SUMMARY')) {
02466               $summary .= $failed_test_summary;
02467        }
02468 
02469        if ($show_html) {
02470               $summary .= "</pre>";
02471        }
02472 
02473        return $summary;
02474 }
02475 
02476 function show_start($start_time)
02477 {
02478        global $html_output, $html_file;
02479 
02480        if ($html_output) {
02481               fwrite($html_file, "<h2>Time Start: " . date('Y-m-d H:i:s', $start_time) . "</h2>\n");
02482               fwrite($html_file, "<table>\n");
02483        }
02484 
02485        echo "TIME START " . date('Y-m-d H:i:s', $start_time) . "\n=====================================================================\n";
02486 }
02487 
02488 function show_end($end_time)
02489 {
02490        global $html_output, $html_file;
02491 
02492        if ($html_output) {
02493               fwrite($html_file, "</table>\n");
02494               fwrite($html_file, "<h2>Time End: " . date('Y-m-d H:i:s', $end_time) . "</h2>\n");
02495        }
02496 
02497        echo "=====================================================================\nTIME END " . date('Y-m-d H:i:s', $end_time) . "\n";
02498 }
02499 
02500 function show_summary()
02501 {
02502        global $html_output, $html_file;
02503 
02504        if ($html_output) {
02505               fwrite($html_file, "<hr/>\n" . get_summary(true, true));
02506        }
02507 
02508        echo get_summary(true, false);
02509 }
02510 
02511 function show_redirect_start($tests, $tested, $tested_file)
02512 {
02513        global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS;
02514 
02515        if ($html_output) {
02516               fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) begin</td></tr>\n");
02517        }
02518 
02519        if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) {
02520                  echo "REDIRECT $tests ($tested [$tested_file]) begin\n";
02521        } else {
02522                  // Write over the last line to avoid random trailing chars on next echo
02523                  echo str_repeat(" ", $line_length), "\r";
02524        }
02525 }
02526 
02527 function show_redirect_ends($tests, $tested, $tested_file)
02528 {
02529        global $html_output, $html_file, $line_length, $SHOW_ONLY_GROUPS;
02530 
02531        if ($html_output) {
02532               fwrite($html_file, "<tr><td colspan='3'>---&gt; $tests ($tested [$tested_file]) done</td></tr>\n");
02533        }
02534 
02535        if (!$SHOW_ONLY_GROUPS || in_array('REDIRECT', $SHOW_ONLY_GROUPS)) {
02536                  echo "REDIRECT $tests ($tested [$tested_file]) done\n";
02537        } else {
02538                  // Write over the last line to avoid random trailing chars on next echo
02539                  echo str_repeat(" ", $line_length), "\r";
02540        }
02541 }
02542 
02543 function show_test($test_idx, $shortname)
02544 {
02545        global $test_cnt;
02546        global $line_length;
02547 
02548        $str = "TEST $test_idx/$test_cnt [$shortname]\r";
02549        $line_length = strlen($str);
02550        echo $str;
02551        flush();
02552 }
02553 
02554 function show_result($result, $tested, $tested_file, $extra = '', $temp_filenames = null)
02555 {
02556        global $html_output, $html_file, $temp_target, $temp_urlbase, $line_length, $SHOW_ONLY_GROUPS;
02557 
02558        if (!$SHOW_ONLY_GROUPS || in_array($result, $SHOW_ONLY_GROUPS)) {
02559               echo "$result $tested [$tested_file] $extra\n";
02560        } else {
02561               // Write over the last line to avoid random trailing chars on next echo
02562               echo str_repeat(" ", $line_length), "\r";
02563        }
02564 
02565        if ($html_output) {
02566 
02567               if (isset($temp_filenames['file']) && file_exists($temp_filenames['file'])) {
02568                      $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['file']);
02569                      $tested = "<a href='$url'>$tested</a>";
02570               }
02571 
02572               if (isset($temp_filenames['skip']) && file_exists($temp_filenames['skip'])) {
02573 
02574                      if (empty($extra)) {
02575                             $extra = "skipif";
02576                      }
02577 
02578                      $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['skip']);
02579                      $extra = "<a href='$url'>$extra</a>";
02580 
02581               } else if (empty($extra)) {
02582                      $extra = "&nbsp;";
02583               }
02584 
02585               if (isset($temp_filenames['diff']) && file_exists($temp_filenames['diff'])) {
02586                      $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['diff']);
02587                      $diff = "<a href='$url'>diff</a>";
02588               } else {
02589                      $diff = "&nbsp;";
02590               }
02591 
02592               if (isset($temp_filenames['mem']) && file_exists($temp_filenames['mem'])) {
02593                      $url = str_replace($temp_target, $temp_urlbase, $temp_filenames['mem']);
02594                      $mem = "<a href='$url'>leaks</a>";
02595               } else {
02596                      $mem = "&nbsp;";
02597               }
02598 
02599               fwrite($html_file,
02600                      "<tr>" .
02601                      "<td>$result</td>" .
02602                      "<td>$tested</td>" .
02603                      "<td>$extra</td>" .
02604                      "<td>$diff</td>" .
02605                      "<td>$mem</td>" .
02606                      "</tr>\n");
02607        }
02608 }
02609 
02610 function save_junit_xml() {
02611        global $JUNIT;
02612        $JUNIT['finished_at']   = microtime(true);
02613        $JUNIT['execution_time']= number_format(($JUNIT['finished_at']-$JUNIT['started_at']), 2);
02614        $JUNIT['result_xml']    =   '<?xml version="1.0" encoding="UTF-8"?>'."\n".
02615                                                         '<testsuites>'."\n".
02616                                                         '<testsuite name="php-src" tests="'.$JUNIT['test_total'].'" failures="'.$JUNIT['test_fail'].'" errors="'.$JUNIT['test_error'].'" skip="'.$JUNIT['test_skip'].'" time="'.$JUNIT['execution_time'].'">'."\n".
02617                                                         $JUNIT['result_xml'].
02618                                                         '</testsuite>'."\n".
02619                                                         '</testsuites>';
02620        fwrite($JUNIT['fp'], $JUNIT['result_xml']);
02621 }
02622 
02623 
02624 /*
02625  * Local variables:
02626  * tab-width: 4
02627  * c-basic-offset: 4
02628  * End:
02629  * vim: noet sw=4 ts=4
02630  */
02631 ?>