PageRenderTime 101ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/opensource.apple.com/source/apache_mod_php/apache_mod_php-43/php/run-tests.php

#
PHP | 2009 lines | 1819 code | 120 blank | 70 comment | 192 complexity | 459dce18b8f9d99e8115c378c854bc05 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, GPL-2.0, BSD-3-Clause, GPL-3.0, MPL-2.0, LGPL-2.0, LGPL-2.1, CC-BY-SA-3.0, IPL-1.0, ISC, AGPL-1.0, AGPL-3.0, JSON, Apache-2.0, 0BSD

Large files files are truncated, but you can click here to view the full file

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <title>run-tests.php</title>
  6. <style type="text/css">
  7. .enscript-comment { font-style: italic; color: rgb(178,34,34); }
  8. .enscript-function-name { font-weight: bold; color: rgb(0,0,255); }
  9. .enscript-variable-name { font-weight: bold; color: rgb(184,134,11); }
  10. .enscript-keyword { font-weight: bold; color: rgb(160,32,240); }
  11. .enscript-reference { font-weight: bold; color: rgb(95,158,160); }
  12. .enscript-string { font-weight: bold; color: rgb(188,143,143); }
  13. .enscript-builtin { font-weight: bold; color: rgb(218,112,214); }
  14. .enscript-type { font-weight: bold; color: rgb(34,139,34); }
  15. .enscript-highlight { text-decoration: underline; color: 0; }
  16. </style>
  17. </head>
  18. <body id="top">
  19. <h1 style="margin:8px;" id="f1">run-tests.php&nbsp;&nbsp;&nbsp;<span style="font-weight: normal; font-size: 0.5em;">[<a href="?txt">plain text</a>]</span></h1>
  20. <hr/>
  21. <div></div>
  22. <pre>
  23. &lt;?php
  24. /*
  25. +----------------------------------------------------------------------+
  26. | PHP Version 5 |
  27. +----------------------------------------------------------------------+
  28. | Copyright (c) 1997-2007 The PHP Group |
  29. +----------------------------------------------------------------------+
  30. | This source file is subject to version 3.01 of the PHP license, |
  31. | that is bundled with this package in the file LICENSE, and is |
  32. | available through the world-wide-web at the following url: |
  33. | <a href="http://www.php.net/license/3_01.txt">http://www.php.net/license/3_01.txt</a> |
  34. | If you did not receive a copy of the PHP license and are unable to |
  35. | obtain it through the world-wide-web, please send a note to |
  36. | <a href="mailto:license@php.net">license@php.net</a> so we can mail you a copy immediately. |
  37. +----------------------------------------------------------------------+
  38. | Authors: Ilia Alshanetsky &lt;<a href="mailto:iliaa@php.net">iliaa@php.net</a>&gt; |
  39. | Preston L. Bannister &lt;<a href="mailto:pbannister@php.net">pbannister@php.net</a>&gt; |
  40. | Marcus Boerger &lt;<a href="mailto:helly@php.net">helly@php.net</a>&gt; |
  41. | Derick Rethans &lt;<a href="mailto:derick@php.net">derick@php.net</a>&gt; |
  42. | Sander Roobol &lt;<a href="mailto:sander@php.net">sander@php.net</a>&gt; |
  43. | (based on version by: Stig Bakken &lt;<a href="mailto:ssb@php.net">ssb@php.net</a>&gt;) |
  44. | (based on the PHP 3 test framework by Rasmus Lerdorf) |
  45. +----------------------------------------------------------------------+
  46. */
  47. /* $Id: run-tests.php,v 1.226.2.37.2.34 2007/07/31 21:29:21 jani Exp $ */
  48. /* Sanity check to ensure that pcre extension needed by this script is available.
  49. * In the event it is not, print a nice error message indicating that this script will
  50. * not run without it.
  51. */
  52. if (!extension_loaded(&quot;pcre&quot;)) {
  53. echo &lt;&lt;&lt;NO_PCRE_ERROR
  54. +-----------------------------------------------------------+
  55. | ! ERROR ! |
  56. | The test-suite requires that you have pcre extension |
  57. | enabled. To enable this extension either compile your PHP |
  58. | with --with-pcre-regex or if you've compiled pcre as a |
  59. | shared module load it via php.ini. |
  60. +-----------------------------------------------------------+
  61. NO_PCRE_ERROR;
  62. exit;
  63. }
  64. if (!function_exists(&quot;proc_open&quot;)) {
  65. echo &lt;&lt;&lt;NO_PROC_OPEN_ERROR
  66. +-----------------------------------------------------------+
  67. | ! ERROR ! |
  68. | The test-suite requires that proc_open() is available. |
  69. | Please check if you disabled it in php.ini. |
  70. +-----------------------------------------------------------+
  71. NO_PROC_OPEN_ERROR;
  72. exit;
  73. }
  74. // store current directory
  75. $CUR_DIR = getcwd();
  76. // change into the PHP source directory.
  77. if (getenv('TEST_PHP_SRCDIR')) {
  78. @chdir(getenv('TEST_PHP_SRCDIR'));
  79. }
  80. // Delete some security related environment variables
  81. putenv('SSH_CLIENT=deleted');
  82. putenv('SSH_AUTH_SOCK=deleted');
  83. putenv('SSH_TTY=deleted');
  84. putenv('SSH_CONNECTION=deleted');
  85. $cwd = getcwd();
  86. set_time_limit(0);
  87. // delete as much output buffers as possible
  88. while(@ob_end_clean());
  89. if (ob_get_level()) echo &quot;Not all buffers were deleted.\n&quot;;
  90. error_reporting(E_ALL);
  91. ini_set('magic_quotes_runtime',0); // this would break tests by modifying EXPECT sections
  92. if (ini_get('safe_mode')) {
  93. echo &lt;&lt;&lt; SAFE_MODE_WARNING
  94. +-----------------------------------------------------------+
  95. | ! WARNING ! |
  96. | You are running the test-suite with &quot;safe_mode&quot; ENABLED ! |
  97. | |
  98. | Chances are high that no test will work at all, |
  99. | depending on how you configured &quot;safe_mode&quot; ! |
  100. +-----------------------------------------------------------+
  101. SAFE_MODE_WARNING;
  102. }
  103. $environment = isset($_ENV) ? $_ENV : array();
  104. // Don't ever guess at the PHP executable location.
  105. // Require the explicit specification.
  106. // Otherwise we could end up testing the wrong file!
  107. if (getenv('TEST_PHP_EXECUTABLE')) {
  108. $php = getenv('TEST_PHP_EXECUTABLE');
  109. if ($php=='auto') {
  110. $php = $cwd.'/sapi/cli/php';
  111. putenv(&quot;TEST_PHP_EXECUTABLE=$php&quot;);
  112. }
  113. $environment['TEST_PHP_EXECUTABLE'] = $php;
  114. }
  115. if (getenv('TEST_PHP_CGI_EXECUTABLE')) {
  116. $php_cgi = getenv('TEST_PHP_CGI_EXECUTABLE');
  117. if ($php_cgi=='auto') {
  118. $php_cgi = $cwd.'/sapi/cgi/php-cgi';
  119. putenv(&quot;TEST_PHP_CGI_EXECUTABLE=$php_cgi&quot;);
  120. }
  121. $environment['TEST_PHP_CGI_EXECUTABLE'] = $php_cgi;
  122. }
  123. if ($argc !=2 || ($argv[1] != '-h' &amp;&amp; $argv[1] != '-help' &amp;&amp; $argv != '--help'))
  124. {
  125. if (empty($php) || !file_exists($php)) {
  126. error(&quot;environment variable TEST_PHP_EXECUTABLE must be set to specify PHP executable!&quot;);
  127. }
  128. if (function_exists('is_executable') &amp;&amp; !@is_executable($php)) {
  129. error(&quot;invalid PHP executable specified by TEST_PHP_EXECUTABLE = &quot; . $php);
  130. }
  131. }
  132. if (getenv('TEST_PHP_LOG_FORMAT')) {
  133. $log_format = strtoupper(getenv('TEST_PHP_LOG_FORMAT'));
  134. } else {
  135. $log_format = 'LEOD';
  136. }
  137. // Check whether a detailed log is wanted.
  138. if (getenv('TEST_PHP_DETAILED')) {
  139. $DETAILED = getenv('TEST_PHP_DETAILED');
  140. } else {
  141. $DETAILED = 0;
  142. }
  143. // Check whether user test dirs are requested.
  144. if (getenv('TEST_PHP_USER')) {
  145. $user_tests = explode (',', getenv('TEST_PHP_USER'));
  146. } else {
  147. $user_tests = array();
  148. }
  149. $exts_to_test = array();
  150. $ini_overwrites = array(
  151. 'output_handler=',
  152. 'open_basedir=',
  153. 'safe_mode=0',
  154. 'disable_functions=',
  155. 'output_buffering=Off',
  156. 'error_reporting=8191',
  157. 'display_errors=1',
  158. 'display_startup_errors=1',
  159. 'log_errors=0',
  160. 'html_errors=0',
  161. 'track_errors=1',
  162. 'report_memleaks=1',
  163. 'report_zend_debug=0',
  164. 'docref_root=',
  165. 'docref_ext=.html',
  166. 'error_prepend_string=',
  167. 'error_append_string=',
  168. 'auto_prepend_file=',
  169. 'auto_append_file=',
  170. 'magic_quotes_runtime=0',
  171. );
  172. function write_information($show_html)
  173. {
  174. global $cwd, $php, $php_info, $user_tests, $ini_overwrites, $pass_options, $exts_to_test;
  175. // Get info from php
  176. $info_file = realpath(dirname(__FILE__)) . '/run-test-info.php';
  177. @unlink($info_file);
  178. $php_info = '&lt;?php echo &quot;
  179. PHP_SAPI : &quot; . PHP_SAPI . &quot;
  180. PHP_VERSION : &quot; . phpversion() . &quot;
  181. ZEND_VERSION: &quot; . zend_version() . &quot;
  182. PHP_OS : &quot; . PHP_OS . &quot; - &quot; . php_uname() . &quot;
  183. INI actual : &quot; . realpath(get_cfg_var(&quot;cfg_file_path&quot;)) . &quot;
  184. More .INIs : &quot; . (function_exists(\'php_ini_scanned_files\') ? str_replace(&quot;\n&quot;,&quot;&quot;, php_ini_scanned_files()) : &quot;** not determined **&quot;); ?&gt;';
  185. save_text($info_file, $php_info);
  186. $info_params = array();
  187. settings2array($ini_overwrites,$info_params);
  188. settings2params($info_params);
  189. $php_info = `$php $pass_options $info_params &quot;$info_file&quot;`;
  190. @unlink($info_file);
  191. define('TESTED_PHP_VERSION', `$php -r &quot;echo PHP_VERSION;&quot;`);
  192. // load list of enabled extensions
  193. save_text($info_file, '&lt;?php echo join(&quot;,&quot;,get_loaded_extensions()); ?&gt;');
  194. $exts_to_test = explode(',',`$php $pass_options $info_params &quot;$info_file&quot;`);
  195. // check for extensions that need special handling and regenerate
  196. $info_params_ex = array(
  197. 'session' =&gt; array('session.auto_start=0'),
  198. 'tidy' =&gt; array('tidy.clean_output=0'),
  199. 'zlib' =&gt; array('zlib.output_compression=Off'),
  200. 'xdebug' =&gt; array('xdebug.default_enable=0'),
  201. );
  202. foreach($info_params_ex as $ext =&gt; $ini_overwrites_ex) {
  203. if (in_array($ext, $exts_to_test)) {
  204. $ini_overwrites = array_merge($ini_overwrites, $ini_overwrites_ex);
  205. }
  206. }
  207. @unlink($info_file);
  208. // Write test context information.
  209. echo &quot;
  210. =====================================================================
  211. CWD : $cwd
  212. PHP : $php $php_info
  213. Extra dirs : &quot;;
  214. foreach ($user_tests as $test_dir) {
  215. echo &quot;{$test_dir}\n &quot;;
  216. }
  217. echo &quot;
  218. =====================================================================
  219. &quot;;
  220. }
  221. // Determine the tests to be run.
  222. $test_files = array();
  223. $redir_tests = array();
  224. $test_results = array();
  225. $PHP_FAILED_TESTS = array('BORKED' =&gt; array(), 'FAILED' =&gt; array(), 'WARNED' =&gt; array(), 'LEAKED' =&gt; array());
  226. // If parameters given assume they represent selected tests to run.
  227. $failed_tests_file= false;
  228. $pass_option_n = false;
  229. $pass_options = '';
  230. $compression = 0;
  231. $output_file = $CUR_DIR . '/php_test_results_' . @date('Ymd_Hi') . '.txt';
  232. if ($compression) {
  233. $output_file = 'compress.zlib://' . $output_file . '.gz';
  234. }
  235. $just_save_results = false;
  236. $leak_check = false;
  237. $html_output = false;
  238. $html_file = null;
  239. $temp_source = null;
  240. $temp_target = null;
  241. $temp_urlbase = null;
  242. $conf_passed = null;
  243. $no_clean = false;
  244. $cfgtypes = array('show', 'keep');
  245. $cfgfiles = array('skip', 'php', 'clean');
  246. $cfg = array();
  247. foreach($cfgtypes as $type) {
  248. $cfg[$type] = array();
  249. foreach($cfgfiles as $file) {
  250. $cfg[$type][$file] = false;
  251. }
  252. }
  253. if (getenv('TEST_PHP_ARGS'))
  254. {
  255. if (!isset($argc) || !$argc || !isset($argv))
  256. {
  257. $argv = array(__FILE__);
  258. }
  259. $argv = array_merge($argv, split(' ', getenv('TEST_PHP_ARGS')));
  260. $argc = count($argv);
  261. }
  262. if (isset($argc) &amp;&amp; $argc &gt; 1) {
  263. for ($i=1; $i&lt;$argc; $i++) {
  264. $is_switch = false;
  265. $switch = substr($argv[$i],1,1);
  266. $repeat = substr($argv[$i],0,1) == '-';
  267. while ($repeat) {
  268. $repeat = false;
  269. if (!$is_switch) {
  270. $switch = substr($argv[$i],1,1);
  271. }
  272. $is_switch = true;
  273. switch($switch) {
  274. case 'r':
  275. case 'l':
  276. $test_list = @file($argv[++$i]);
  277. if ($test_list) {
  278. foreach($test_list as $test) {
  279. $matches = array();
  280. if (preg_match('/^#.*\[(.*)\]\:\s+(.*)$/', $test, $matches)) {
  281. $redir_tests[] = array($matches[1], $matches[2]);
  282. } else if (strlen($test)) {
  283. $test_files[] = trim($test);
  284. }
  285. }
  286. }
  287. if ($switch != 'l') {
  288. break;
  289. }
  290. $i--;
  291. // break left intentionally
  292. case 'w':
  293. $failed_tests_file = fopen($argv[++$i], 'w+t');
  294. break;
  295. case 'a':
  296. $failed_tests_file = fopen($argv[++$i], 'a+t');
  297. break;
  298. case 'c':
  299. $conf_passed = $argv[++$i];
  300. break;
  301. case 'd':
  302. $ini_overwrites[] = $argv[++$i];
  303. break;
  304. //case 'h'
  305. case '--keep-all':
  306. foreach($cfgfiles as $file) {
  307. $cfg['keep'][$file] = true;
  308. }
  309. break;
  310. case '--keep-skip':
  311. $cfg['keep']['skip'] = true;
  312. break;
  313. case '--keep-php':
  314. $cfg['keep']['php'] = true;
  315. break;
  316. case '--keep-clean':
  317. $cfg['keep']['clean'] = true;
  318. break;
  319. //case 'l'
  320. case 'm':
  321. $leak_check = true;
  322. break;
  323. case 'n':
  324. if (!$pass_option_n) {
  325. $pass_options .= ' -n';
  326. }
  327. $pass_option_n = true;
  328. break;
  329. case 'N':
  330. // this is always native
  331. break;
  332. case '--no-clean':
  333. $no_clean = true;
  334. break;
  335. case 'q':
  336. putenv('NO_INTERACTION=1');
  337. break;
  338. //case 'r'
  339. case 's':
  340. $output_file = $argv[++$i];
  341. $just_save_results = true;
  342. break;
  343. case '--show-all':
  344. foreach($cfgfiles as $file) {
  345. $cfg['show'][$file] = true;
  346. }
  347. break;
  348. case '--show-skip':
  349. $cfg['show']['skip'] = true;
  350. break;
  351. case '--show-php':
  352. $cfg['show']['php'] = true;
  353. break;
  354. case '--show-clean':
  355. $cfg['show']['clean'] = true;
  356. break;
  357. case '--temp-source':
  358. $temp_source = $argv[++$i];
  359. break;
  360. case '--temp-target':
  361. $temp_target = $argv[++$i];
  362. if ($temp_urlbase) {
  363. $temp_urlbase = $temp_target;
  364. }
  365. break;
  366. case '--temp-urlbase':
  367. $temp_urlbase = $argv[++$i];
  368. break;
  369. case 'v':
  370. case '--verbose':
  371. $DETAILED = true;
  372. break;
  373. //case 'w'
  374. case '-':
  375. // repeat check with full switch
  376. $switch = $argv[$i];
  377. if ($switch != '-') {
  378. $repeat = true;
  379. }
  380. break;
  381. case '--html':
  382. $html_file = @fopen($argv[++$i], 'wt');
  383. $html_output = is_resource($html_file);
  384. break;
  385. case '--version':
  386. echo '$Revision: 1.226.2.37.2.34 $'.&quot;\n&quot;;
  387. exit(1);
  388. case 'u':
  389. case 'U':
  390. // Allow using u or U for forward compatibility
  391. break;
  392. default:
  393. echo &quot;Illegal switch '$switch' specified!\n&quot;;
  394. case 'h':
  395. case '-help':
  396. case '--help':
  397. echo &lt;&lt;&lt;HELP
  398. Synopsis:
  399. php run-tests.php [options] [files] [directories]
  400. Options:
  401. -l &lt;file&gt; Read the testfiles to be executed from &lt;file&gt;. After the test
  402. has finished all failed tests are written to the same &lt;file&gt;.
  403. If the list is empty and no further test is specified then
  404. all tests are executed (same as: -r &lt;file&gt; -w &lt;file&gt;).
  405. -r &lt;file&gt; Read the testfiles to be executed from &lt;file&gt;.
  406. -w &lt;file&gt; Write a list of all failed tests to &lt;file&gt;.
  407. -a &lt;file&gt; Same as -w but append rather then truncating &lt;file&gt;.
  408. -c &lt;file&gt; Look for php.ini in directory &lt;file&gt; or use &lt;file&gt; as ini.
  409. -n Pass -n option to the php binary (Do not use a php.ini).
  410. -d foo=bar Pass -d option to the php binary (Define INI entry foo
  411. with value 'bar').
  412. -m Test for memory leaks with Valgrind.
  413. -N Always set (Test with unicode_semantics set off in PHP 6).
  414. -s &lt;file&gt; Write output to &lt;file&gt;.
  415. -q Quiet, no user interaction (same as environment NO_INTERACTION).
  416. --verbose
  417. -v Verbose mode.
  418. --help
  419. -h This Help.
  420. --html &lt;file&gt; Generate HTML output.
  421. --temp-source &lt;sdir&gt; --temp-target &lt;tdir&gt; [--temp-urlbase &lt;url&gt;]
  422. Write temporary files to &lt;tdir&gt; by replacing &lt;sdir&gt; from the
  423. filenames to generate with &lt;tdir&gt;. If --html is being used and
  424. &lt;url&gt; given then the generated links are relative and prefixed
  425. with the given url. In general you want to make &lt;sdir&gt; the path
  426. to your source files and &lt;tdir&gt; some pach in your web page
  427. hierarchy with &lt;url&gt; pointing to &lt;tdir&gt;.
  428. --keep-[all|php|skip|clean]
  429. Do not delete 'all' files, 'php' test file, 'skip' or 'clean'
  430. file.
  431. --show-[all|php|skip|clean]
  432. Show 'all' files, 'php' test file, 'skip' or 'clean' file.
  433. --no-clean Do not execute clean section if any.
  434. HELP;
  435. exit(1);
  436. }
  437. }
  438. if (!$is_switch) {
  439. $testfile = realpath($argv[$i]);
  440. if (!$testfile &amp;&amp; strpos($argv[$i], '*') !== false &amp;&amp; function_exists('glob')) {
  441. if (preg_match(&quot;/\.phpt$/&quot;, $argv[$i])) {
  442. $pattern_match = glob($argv[$i]);
  443. } else if (preg_match(&quot;/\*$/&quot;, $argv[$i])) {
  444. $pattern_match = glob($argv[$i] . '.phpt');
  445. } else {
  446. die(&quot;bogus test name &quot; . $argv[$i] . &quot;\n&quot;);
  447. }
  448. if (is_array($pattern_match)) {
  449. $test_files = array_merge($test_files, $pattern_match);
  450. }
  451. } else if (is_dir($testfile)) {
  452. find_files($testfile);
  453. } else if (preg_match(&quot;/\.phpt$/&quot;, $testfile)) {
  454. $test_files[] = $testfile;
  455. } else {
  456. die(&quot;bogus test name &quot; . $argv[$i] . &quot;\n&quot;);
  457. }
  458. }
  459. }
  460. if (strlen($conf_passed))
  461. {
  462. $pass_options .= &quot; -c '$conf_passed'&quot;;
  463. }
  464. $test_files = array_unique($test_files);
  465. $test_files = array_merge($test_files, $redir_tests);
  466. // Run selected tests.
  467. $test_cnt = count($test_files);
  468. if ($test_cnt) {
  469. write_information($html_output);
  470. usort($test_files, &quot;test_sort&quot;);
  471. $start_time = time();
  472. if (!$html_output) {
  473. echo &quot;Running selected tests.\n&quot;;
  474. } else {
  475. show_start($start_time);
  476. }
  477. $test_idx = 0;
  478. run_all_tests($test_files, $environment);
  479. $end_time = time();
  480. if ($html_output) {
  481. show_end($end_time);
  482. }
  483. if ($failed_tests_file) {
  484. fclose($failed_tests_file);
  485. }
  486. if (count($test_files) || count($test_results)) {
  487. compute_summary();
  488. if ($html_output) {
  489. fwrite($html_file, &quot;&lt;hr/&gt;\n&quot; . get_summary(false, true));
  490. }
  491. echo &quot;=====================================================================&quot;;
  492. echo get_summary(false, false);
  493. }
  494. if ($html_output) {
  495. fclose($html_file);
  496. }
  497. if (getenv('REPORT_EXIT_STATUS') == 1 and preg_match('/FAILED(?: |$)/', implode(' ', $test_results))) {
  498. exit(1);
  499. }
  500. exit(0);
  501. }
  502. }
  503. write_information($html_output);
  504. // Compile a list of all test files (*.phpt).
  505. $test_files = array();
  506. $exts_tested = count($exts_to_test);
  507. $exts_skipped = 0;
  508. $ignored_by_ext = 0;
  509. sort($exts_to_test);
  510. $test_dirs = array();
  511. $optionals = array('tests', 'ext', 'Zend', 'ZendEngine2', 'sapi/cli', 'sapi/cgi');
  512. foreach($optionals as $dir) {
  513. if (@filetype($dir) == 'dir') {
  514. $test_dirs[] = $dir;
  515. }
  516. }
  517. // Convert extension names to lowercase
  518. foreach ($exts_to_test as $key =&gt; $val) {
  519. $exts_to_test[$key] = strtolower($val);
  520. }
  521. foreach ($test_dirs as $dir) {
  522. find_files(&quot;{$cwd}/{$dir}&quot;, ($dir == 'ext'));
  523. }
  524. foreach ($user_tests as $dir) {
  525. find_files($dir, ($dir == 'ext'));
  526. }
  527. function find_files($dir,$is_ext_dir=FALSE,$ignore=FALSE)
  528. {
  529. global $test_files, $exts_to_test, $ignored_by_ext, $exts_skipped, $exts_tested;
  530. $o = opendir($dir) or error(&quot;cannot open directory: $dir&quot;);
  531. while (($name = readdir($o)) !== FALSE) {
  532. if (is_dir(&quot;{$dir}/{$name}&quot;) &amp;&amp; !in_array($name, array('.', '..', 'CVS'))) {
  533. $skip_ext = ($is_ext_dir &amp;&amp; !in_array(strtolower($name), $exts_to_test));
  534. if ($skip_ext) {
  535. $exts_skipped++;
  536. }
  537. find_files(&quot;{$dir}/{$name}&quot;, FALSE, $ignore || $skip_ext);
  538. }
  539. // Cleanup any left-over tmp files from last run.
  540. if (substr($name, -4) == '.tmp') {
  541. @unlink(&quot;$dir/$name&quot;);
  542. continue;
  543. }
  544. // Otherwise we're only interested in *.phpt files.
  545. if (substr($name, -5) == '.phpt') {
  546. if ($ignore) {
  547. $ignored_by_ext++;
  548. } else {
  549. $testfile = realpath(&quot;{$dir}/{$name}&quot;);
  550. $test_files[] = $testfile;
  551. }
  552. }
  553. }
  554. closedir($o);
  555. }
  556. function test_name($name)
  557. {
  558. if (is_array($name)) {
  559. return $name[0] . ':' . $name[1];
  560. } else {
  561. return $name;
  562. }
  563. }
  564. function test_sort($a, $b)
  565. {
  566. global $cwd;
  567. $a = test_name($a);
  568. $b = test_name($b);
  569. $ta = strpos($a, &quot;{$cwd}/tests&quot;)===0 ? 1 + (strpos($a, &quot;{$cwd}/tests/run-test&quot;)===0 ? 1 : 0) : 0;
  570. $tb = strpos($b, &quot;{$cwd}/tests&quot;)===0 ? 1 + (strpos($b, &quot;{$cwd}/tests/run-test&quot;)===0 ? 1 : 0) : 0;
  571. if ($ta == $tb) {
  572. return strcmp($a, $b);
  573. } else {
  574. return $tb - $ta;
  575. }
  576. }
  577. $test_files = array_unique($test_files);
  578. usort($test_files, &quot;test_sort&quot;);
  579. $start_time = time();
  580. show_start($start_time);
  581. $test_cnt = count($test_files);
  582. $test_idx = 0;
  583. run_all_tests($test_files, $environment);
  584. $end_time = time();
  585. if ($failed_tests_file) {
  586. fclose($failed_tests_file);
  587. }
  588. // Summarize results
  589. if (0 == count($test_results)) {
  590. echo &quot;No tests were run.\n&quot;;
  591. return;
  592. }
  593. compute_summary();
  594. show_end($end_time);
  595. show_summary();
  596. if ($html_output) {
  597. fclose($html_file);
  598. }
  599. define('PHP_QA_EMAIL', '<a href="mailto:qa-reports@lists.php.net">qa-reports@lists.php.net</a>');
  600. define('QA_SUBMISSION_PAGE', '<a href="http://qa.php.net/buildtest-process.php">http://qa.php.net/buildtest-process.php</a>');
  601. /* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */
  602. if (!getenv('NO_INTERACTION')) {
  603. $fp = fopen(&quot;php://stdin&quot;, &quot;r+&quot;);
  604. if ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['WARNED'] || $sum_results['LEAKED']) {
  605. echo &quot;\nYou may have found a problem in PHP.&quot;;
  606. }
  607. echo &quot;\nWe would like to send this report automatically to the\n&quot;;
  608. echo &quot;PHP QA team, to give us a better understanding of how\nthe test cases are doing. If you don't want to send it\n&quot;;
  609. echo &quot;immediately, you can choose \&quot;s\&quot; to save the report to\na file that you can send us later.\n&quot;;
  610. echo &quot;Do you want to send this report now? [Yns]: &quot;;
  611. flush();
  612. $user_input = fgets($fp, 10);
  613. $just_save_results = (strtolower($user_input[0]) == 's');
  614. }
  615. if ($just_save_results || !getenv('NO_INTERACTION')) {
  616. if ($just_save_results || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') {
  617. /*
  618. * Collect information about the host system for our report
  619. * Fetch phpinfo() output so that we can see the PHP enviroment
  620. * Make an archive of all the failed tests
  621. * Send an email
  622. */
  623. if ($just_save_results)
  624. {
  625. $user_input = 's';
  626. }
  627. /* Ask the user to provide an email address, so that QA team can contact the user */
  628. if (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) {
  629. echo &quot;\nPlease enter your email address.\n(Your address will be mangled so that it will not go out on any\nmailinglist in plain text): &quot;;
  630. flush();
  631. $user_email = trim(fgets($fp, 1024));
  632. $user_email = str_replace(&quot;@&quot;, &quot; at &quot;, str_replace(&quot;.&quot;, &quot; dot &quot;, $user_email));
  633. }
  634. $failed_tests_data = '';
  635. $sep = &quot;\n&quot; . str_repeat('=', 80) . &quot;\n&quot;;
  636. $failed_tests_data .= $failed_test_summary . &quot;\n&quot;;
  637. $failed_tests_data .= get_summary(true, false) . &quot;\n&quot;;
  638. if ($sum_results['FAILED']) {
  639. foreach ($PHP_FAILED_TESTS['FAILED'] as $test_info) {
  640. $failed_tests_data .= $sep . $test_info['name'] . $test_info['info'];
  641. $failed_tests_data .= $sep . file_get_contents(realpath($test_info['output']));
  642. $failed_tests_data .= $sep . file_get_contents(realpath($test_info['diff']));
  643. $failed_tests_data .= $sep . &quot;\n\n&quot;;
  644. }
  645. $status = &quot;failed&quot;;
  646. } else {
  647. $status = &quot;success&quot;;
  648. }
  649. $failed_tests_data .= &quot;\n&quot; . $sep . 'BUILD ENVIRONMENT' . $sep;
  650. $failed_tests_data .= &quot;OS:\n&quot; . PHP_OS . &quot; - &quot; . php_uname() . &quot;\n\n&quot;;
  651. $ldd = $autoconf = $sys_libtool = $libtool = $compiler = 'N/A';
  652. if (substr(PHP_OS, 0, 3) != &quot;WIN&quot;) {
  653. /* If PHP_AUTOCONF is set, use it; otherwise, use 'autoconf'. */
  654. if (getenv('PHP_AUTOCONF')) {
  655. $autoconf = shell_exec(getenv('PHP_AUTOCONF') . ' --version');
  656. } else {
  657. $autoconf = shell_exec('autoconf --version');
  658. }
  659. /* Always use the generated libtool - Mac OSX uses 'glibtool' */
  660. $libtool = shell_exec($CUR_DIR . '/libtool --version');
  661. /* Use shtool to find out if there is glibtool present (MacOSX) */
  662. $sys_libtool_path = shell_exec(dirname(__FILE__) . '/build/shtool path glibtool libtool');
  663. if ($sys_libtool_path) {
  664. $sys_libtool = shell_exec(str_replace(&quot;\n&quot;, &quot;&quot;, $sys_libtool_path) . ' --version');
  665. }
  666. /* Try the most common flags for 'version' */
  667. $flags = array('-v', '-V', '--version');
  668. $cc_status=0;
  669. foreach($flags AS $flag) {
  670. system(getenv('CC').&quot; $flag &gt;/dev/null 2&gt;&amp;1&quot;, $cc_status);
  671. if ($cc_status == 0) {
  672. $compiler = shell_exec(getenv('CC').&quot; $flag 2&gt;&amp;1&quot;);
  673. break;
  674. }
  675. }
  676. $ldd = shell_exec(&quot;ldd $php 2&gt;/dev/null&quot;);
  677. }
  678. $failed_tests_data .= &quot;Autoconf:\n$autoconf\n&quot;;
  679. $failed_tests_data .= &quot;Bundled Libtool:\n$libtool\n&quot;;
  680. $failed_tests_data .= &quot;System Libtool:\n$sys_libtool\n&quot;;
  681. $failed_tests_data .= &quot;Compiler:\n$compiler\n&quot;;
  682. $failed_tests_data .= &quot;Bison:\n&quot;. @shell_exec('bison --version 2&gt;/dev/null'). &quot;\n&quot;;
  683. $failed_tests_data .= &quot;Libraries:\n$ldd\n&quot;;
  684. $failed_tests_data .= &quot;\n&quot;;
  685. if (isset($user_email)) {
  686. $failed_tests_data .= &quot;User's E-mail: &quot;.$user_email.&quot;\n\n&quot;;
  687. }
  688. $failed_tests_data .= $sep . &quot;PHPINFO&quot; . $sep;
  689. $failed_tests_data .= shell_exec($php.' -dhtml_errors=0 -i');
  690. if ($just_save_results || !mail_qa_team($failed_tests_data, $compression, $status)) {
  691. file_put_contents($output_file, $failed_tests_data);
  692. if (!$just_save_results) {
  693. echo &quot;\nThe test script was unable to automatically send the report to PHP's QA Team\n&quot;;
  694. }
  695. echo &quot;Please send &quot;.$output_file.&quot; to &quot;.PHP_QA_EMAIL.&quot; manually, thank you.\n&quot;;
  696. } else {
  697. fwrite($fp, &quot;\nThank you for helping to make PHP better.\n&quot;);
  698. fclose($fp);
  699. }
  700. }
  701. }
  702. if (getenv('REPORT_EXIT_STATUS') == 1 and $sum_results['FAILED']) {
  703. exit(1);
  704. }
  705. exit(0);
  706. //
  707. // Send Email to QA Team
  708. //
  709. function mail_qa_team($data, $compression, $status = FALSE)
  710. {
  711. $url_bits = parse_url(QA_SUBMISSION_PAGE);
  712. if (empty($url_bits['port'])) $url_bits['port'] = 80;
  713. $data = &quot;php_test_data=&quot; . urlencode(base64_encode(str_replace(&quot;\00&quot;, '[0x0]', $data)));
  714. $data_length = strlen($data);
  715. $fs = fsockopen($url_bits['host'], $url_bits['port'], $errno, $errstr, 10);
  716. if (!$fs) {
  717. return FALSE;
  718. }
  719. $php_version = urlencode(TESTED_PHP_VERSION);
  720. echo &quot;\nPosting to {$url_bits['host']} {$url_bits['path']}\n&quot;;
  721. fwrite($fs, &quot;POST &quot;.$url_bits['path'].&quot;?status=$status&amp;version=$php_version HTTP/1.1\r\n&quot;);
  722. fwrite($fs, &quot;Host: &quot;.$url_bits['host'].&quot;\r\n&quot;);
  723. fwrite($fs, &quot;User-Agent: QA Browser 0.1\r\n&quot;);
  724. fwrite($fs, &quot;Content-Type: application/x-www-form-urlencoded\r\n&quot;);
  725. fwrite($fs, &quot;Content-Length: &quot;.$data_length.&quot;\r\n\r\n&quot;);
  726. fwrite($fs, $data);
  727. fwrite($fs, &quot;\r\n\r\n&quot;);
  728. fclose($fs);
  729. return 1;
  730. }
  731. //
  732. // Write the given text to a temporary file, and return the filename.
  733. //
  734. function save_text($filename, $text, $filename_copy = null)
  735. {
  736. global $DETAILED;
  737. if ($filename_copy &amp;&amp; $filename_copy != $filename) {
  738. if (@file_put_contents($filename_copy, $text) === false) {
  739. error(&quot;Cannot open file '&quot; . $filename_copy . &quot;' (save_text)&quot;);
  740. }
  741. }
  742. if (@file_put_contents($filename, $text) === false) {
  743. error(&quot;Cannot open file '&quot; . $filename . &quot;' (save_text)&quot;);
  744. }
  745. if (1 &lt; $DETAILED) echo &quot;
  746. FILE $filename {{{
  747. $text
  748. }}}
  749. &quot;;
  750. }
  751. //
  752. // Write an error in a format recognizable to Emacs or MSVC.
  753. //
  754. function error_report($testname, $logname, $tested)
  755. {
  756. $testname = realpath($testname);
  757. $logname = realpath($logname);
  758. switch (strtoupper(getenv('TEST_PHP_ERROR_STYLE'))) {
  759. case 'MSVC':
  760. echo $testname . &quot;(1) : $tested\n&quot;;
  761. echo $logname . &quot;(1) : $tested\n&quot;;
  762. break;
  763. case 'EMACS':
  764. echo $testname . &quot;:1: $tested\n&quot;;
  765. echo $logname . &quot;:1: $tested\n&quot;;
  766. break;
  767. }
  768. }
  769. function system_with_timeout($commandline, $env = null, $stdin = null)
  770. {
  771. global $leak_check;
  772. $data = &quot;&quot;;
  773. $proc = proc_open($commandline, array(
  774. 0 =&gt; array('pipe', 'r'),
  775. 1 =&gt; array('pipe', 'w'),
  776. 2 =&gt; array('pipe', 'w')
  777. ), $pipes, null, $env, array(&quot;suppress_errors&quot; =&gt; true));
  778. if (!$proc)
  779. return false;
  780. if (is_string($stdin)) {
  781. fwrite($pipes[0], $stdin);
  782. }
  783. fclose($pipes[0]);
  784. while (true) {
  785. /* hide errors from interrupted syscalls */
  786. $r = $pipes;
  787. $w = null;
  788. $e = null;
  789. $n = @stream_select($r, $w, $e, $leak_check ? 300 : 60);
  790. if ($n === 0) {
  791. /* timed out */
  792. $data .= &quot;\n ** ERROR: process timed out **\n&quot;;
  793. proc_terminate($proc);
  794. return $data;
  795. } else if ($n &gt; 0) {
  796. $line = fread($pipes[1], 8192);
  797. if (strlen($line) == 0) {
  798. /* EOF */
  799. break;
  800. }
  801. $data .= $line;
  802. }
  803. }
  804. $stat = proc_get_status($proc);
  805. if ($stat['signaled']) {
  806. $data .= &quot;\nTermsig=&quot;.$stat['stopsig'];
  807. }
  808. $code = proc_close($proc);
  809. return $data;
  810. }
  811. function run_all_tests($test_files, $env, $redir_tested = NULL)
  812. {
  813. global $test_results, $failed_tests_file, $php, $test_cnt, $test_idx;
  814. foreach($test_files as $name)
  815. {
  816. if (is_array($name))
  817. {
  818. $index = &quot;# $name[1]: $name[0]&quot;;
  819. if ($redir_tested)
  820. {
  821. $name = $name[0];
  822. }
  823. }
  824. else if ($redir_tested)
  825. {
  826. $index = &quot;# $redir_tested: $name&quot;;
  827. }
  828. else
  829. {
  830. $index = $name;
  831. }
  832. $test_idx++;
  833. $result = run_test($php, $name, $env);
  834. if (!is_array($name) &amp;&amp; $result != 'REDIR')
  835. {
  836. $test_results[$index] = $result;
  837. if ($failed_tests_file &amp;&amp; ($result == 'FAILED' || $result == 'WARNED' || $result == 'LEAKED'))
  838. {
  839. fwrite($failed_tests_file, &quot;$index\n&quot;);
  840. }
  841. }
  842. }
  843. }
  844. //
  845. // Run an individual test case.
  846. //
  847. function run_test($php, $file, $env)
  848. {
  849. global $log_format, $info_params, $ini_overwrites, $cwd, $PHP_FAILED_TESTS;
  850. global $pass_options, $DETAILED, $IN_REDIRECT, $test_cnt, $test_idx;
  851. global $leak_check, $temp_source, $temp_target, $cfg, $environment;
  852. global $no_clean;
  853. $temp_filenames = null;
  854. $org_file = $file;
  855. if (isset($env['TEST_PHP_CGI_EXECUTABLE'])) {
  856. $php_cgi = $env['TEST_PHP_CGI_EXECUTABLE'];
  857. }
  858. if (is_array($file)) $file = $file[0];
  859. if ($DETAILED) echo &quot;
  860. =================
  861. TEST $file
  862. &quot;;
  863. // Load the sections of the test file.
  864. $section_text = array(
  865. 'TEST' =&gt; '',
  866. 'SKIPIF' =&gt; '',
  867. 'GET' =&gt; '',
  868. 'COOKIE' =&gt; '',
  869. 'POST_RAW' =&gt; '',
  870. 'POST' =&gt; '',
  871. 'UPLOAD' =&gt; '',
  872. 'ARGS' =&gt; '',
  873. );
  874. $fp = fopen($file, &quot;rt&quot;) or error(&quot;Cannot open test file: $file&quot;);
  875. $borked = false;
  876. $bork_info = '';
  877. if (!feof($fp)) {
  878. $line = fgets($fp);
  879. } else {
  880. $bork_info = &quot;empty test [$file]&quot;;
  881. $borked = true;
  882. }
  883. if (strncmp('--TEST--', $line, 8)) {
  884. $bork_info = &quot;tests must start with --TEST-- [$file]&quot;;
  885. $borked = true;
  886. }
  887. $section = 'TEST';
  888. $secfile = false;
  889. $secdone = false;
  890. while (!feof($fp)) {
  891. $line = fgets($fp);
  892. // Match the beginning of a section.
  893. if (preg_match('/^--([_A-Z]+)--/', $line, $r)) {
  894. $section = $r[1];
  895. $section_text[$section] = '';
  896. $secfile = $section == 'FILE' || $section == 'FILEEOF';
  897. $secdone = false;
  898. continue;
  899. }
  900. // Add to the section text.
  901. if (!$secdone) {
  902. $section_text[$section] .= $line;
  903. }
  904. // End of actual test?
  905. if ($secfile &amp;&amp; preg_match('/^===DONE===$/', $line)) {
  906. $secdone = true;
  907. }
  908. }
  909. // the redirect section allows a set of tests to be reused outside of
  910. // a given test dir
  911. if (@count($section_text['REDIRECTTEST']) == 1) {
  912. if ($IN_REDIRECT) {
  913. $borked = true;
  914. $bork_info = &quot;Can't redirect a test from within a redirected test&quot;;
  915. } else {
  916. $borked = false;
  917. }
  918. } else {
  919. if (@count($section_text['FILE']) + @count($section_text['FILEEOF']) != 1) {
  920. $bork_info = &quot;missing section --FILE--&quot;;
  921. $borked = true;
  922. }
  923. if (@count($section_text['FILEEOF']) == 1) {
  924. $section_text['FILE'] = preg_replace(&quot;/[\r\n]+$/&quot;, '', $section_text['FILEEOF']);
  925. unset($section_text['FILEEOF']);
  926. }
  927. if ((@count($section_text['EXPECT']) + @count($section_text['EXPECTF']) + @count($section_text['EXPECTREGEX'])) != 1) {
  928. $bork_info = &quot;missing section --EXPECT--, --EXPECTF-- or --EXPECTREGEX--&quot;;
  929. $borked = true;
  930. }
  931. }
  932. fclose($fp);
  933. $shortname = str_replace($cwd.'/', '', $file);
  934. $tested_file = $shortname;
  935. if ($borked) {
  936. show_result(&quot;BORK&quot;, $bork_info, $tested_file);
  937. $PHP_FAILED_TESTS['BORKED'][] = array (
  938. 'name' =&gt; $file,
  939. 'test_name' =&gt; '',
  940. 'output' =&gt; '',
  941. 'diff' =&gt; '',
  942. 'info' =&gt; &quot;$bork_info [$file]&quot;,
  943. );
  944. return 'BORKED';
  945. }
  946. $tested = trim($section_text['TEST']);
  947. /* For GET/POST tests, check if cgi sapi is available and if it is, use it. */
  948. if (!empty($section_text['GET']) || !empty($section_text['POST']) || !empty($section_text['POST_RAW']) || !empty($section_text['COOKIE'])) {
  949. if (isset($php_cgi)) {
  950. $old_php = $php;
  951. $php = $php_cgi .' -C ';
  952. } elseif (!strncasecmp(PHP_OS, &quot;win&quot;, 3) &amp;&amp; file_exists(dirname($php) .&quot;/php-cgi.exe&quot;)) {
  953. $old_php = $php;
  954. $php = realpath(dirname($php) .&quot;/php-cgi.exe&quot;) .' -C ';
  955. } else {
  956. if (file_exists(dirname($php).&quot;/../../sapi/cgi/php-cgi&quot;)) {
  957. $old_php = $php;
  958. $php = realpath(dirname($php).&quot;/../../sapi/cgi/php-cgi&quot;) . ' -C ';
  959. } else if (file_exists(&quot;./sapi/cgi/php-cgi&quot;)) {
  960. $old_php = $php;
  961. $php = realpath(&quot;./sapi/cgi/php-cgi&quot;) . ' -C ';
  962. } else {
  963. show_result(&quot;SKIP&quot;, $tested, $tested_file, &quot;reason: CGI not available&quot;);
  964. return 'SKIPPED';
  965. }
  966. }
  967. }
  968. show_test($test_idx, $shortname);
  969. if (is_array($IN_REDIRECT)) {
  970. $temp_dir = $test_dir = $IN_REDIRECT['dir'];
  971. } else {
  972. $temp_dir = $test_dir = realpath(dirname($file));
  973. }
  974. if ($temp_source &amp;&amp; $temp_target) {
  975. $temp_dir = str_replace($temp_source, $temp_target, $temp_dir);
  976. }
  977. $main_file_name = basename($file,'phpt');
  978. $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff';
  979. $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log';
  980. $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp';
  981. $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out';
  982. $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem';
  983. $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
  984. $test_file = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'php';
  985. $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
  986. $test_skipif = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php';
  987. $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
  988. $test_clean = $test_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php';
  989. $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('/phpt.');
  990. $tmp_relative_file = str_replace(dirname(__FILE__).DIRECTORY_SEPARATOR, '', $test_file) . 't';
  991. if ($temp_source &amp;&amp; $temp_target) {
  992. $temp_skipif .= 's';
  993. $temp_file .= 's';
  994. $temp_clean .= 's';
  995. $copy_file = $temp_dir . DIRECTORY_SEPARATOR . basename(is_array($file) ? $file[1] : $file).'.phps';
  996. if (!is_dir(dirname($copy_file))) {
  997. @mkdir(dirname($copy_file), 0777, true) or error(&quot;Cannot create output directory - &quot; . dirname($copy_file));
  998. }
  999. if (isset($section_text['FILE'])) {
  1000. save_text($copy_file, $section_text['FILE']);
  1001. }
  1002. $temp_filenames = array(
  1003. 'file' =&gt; $copy_file,
  1004. 'diff' =&gt; $diff_filename,
  1005. 'log' =&gt; $log_filename,
  1006. 'exp' =&gt; $exp_filename,
  1007. 'out' =&gt; $output_filename,
  1008. 'mem' =&gt; $memcheck_filename,
  1009. 'php' =&gt; $temp_file,
  1010. 'skip' =&gt; $temp_skipif,
  1011. 'clean'=&gt; $temp_clean);
  1012. }
  1013. if (is_array($IN_REDIRECT)) {
  1014. $tested = $IN_REDIRECT['prefix'] . ' ' . trim($section_text['TEST']);
  1015. $tested_file = $tmp_relative_file;
  1016. $section_text['FILE'] = &quot;# original source file: $shortname\n&quot; . $section_text['FILE'];
  1017. }
  1018. // unlink old test results
  1019. @unlink($diff_filename);
  1020. @unlink($log_filename);
  1021. @unlink($exp_filename);
  1022. @unlink($output_filename);
  1023. @unlink($memcheck_filename);
  1024. @unlink($temp_file);
  1025. @unlink($test_file);
  1026. @unlink($temp_skipif);
  1027. @unlink($test_skipif);
  1028. @unlink($tmp_post);
  1029. @unlink($temp_clean);
  1030. @unlink($test_clean);
  1031. // Reset environment from any previous test.
  1032. $env['REDIRECT_STATUS']='';
  1033. $env['QUERY_STRING']='';
  1034. $env['PATH_TRANSLATED']='';
  1035. $env['SCRIPT_FILENAME']='';
  1036. $env['REQUEST_METHOD']='';
  1037. $env['CONTENT_TYPE']='';
  1038. $env['CONTENT_LENGTH']='';
  1039. if (!empty($section_text['ENV'])) {
  1040. foreach(explode(&quot;\n&quot;, trim($section_text['ENV'])) as $e) {
  1041. $e = explode('=',trim($e),2);
  1042. if (!empty($e[0]) &amp;&amp; isset($e[1])) {
  1043. $env[$e[0]] = $e[1];
  1044. }
  1045. }
  1046. }
  1047. // Default ini settings
  1048. $ini_settings = array();
  1049. // additional ini overwrites
  1050. //$ini_overwrites[] = 'setting=value';
  1051. settings2array($ini_overwrites, $ini_settings);
  1052. // Any special ini settings
  1053. // these may overwrite the test defaults...
  1054. if (array_key_exists('INI', $section_text)) {
  1055. if (strpos($section_text['INI'], '{PWD}') !== false) {
  1056. $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']);
  1057. }
  1058. settings2array(preg_split( &quot;/[\n\r]+/&quot;, $section_text['INI']), $ini_settings);
  1059. }
  1060. settings2params($ini_settings);
  1061. // Check if test should be skipped.
  1062. $info = '';
  1063. $warn = false;
  1064. if (array_key_exists('SKIPIF', $section_text)) {
  1065. if (trim($section_text['SKIPIF'])) {
  1066. if ($cfg['show']['skip']) {
  1067. echo &quot;\n========SKIP========\n&quot;;
  1068. echo $section_text['SKIPIF'];
  1069. echo &quot;========DONE========\n&quot;;
  1070. }
  1071. save_text($test_skipif, $section_text['SKIPIF'], $temp_skipif);
  1072. $extra = substr(PHP_OS, 0, 3) !== &quot;WIN&quot; ?
  1073. &quot;unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;&quot;: &quot;&quot;;
  1074. if ($leak_check) {
  1075. $env['USE_ZEND_ALLOC'] = '0';
  1076. } else {
  1077. $env['USE_ZEND_ALLOC'] = '1';
  1078. }
  1079. $output = system_with_timeout(&quot;$extra $php $pass_options -q $ini_settings $test_skipif&quot;, $env);
  1080. if (!$cfg['keep']['skip']) {
  1081. @unlink($test_skipif);
  1082. }
  1083. if (!strncasecmp('skip', ltrim($output), 4)) {
  1084. if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) {
  1085. show_result(&quot;SKIP&quot;, $tested, $tested_file, &quot;reason: $m[1]&quot;, $temp_filenames);
  1086. } else {
  1087. show_result(&quot;SKIP&quot;, $tested, $tested_file, '', $temp_filenames);
  1088. }
  1089. if (isset($old_php)) {
  1090. $php = $old_php;
  1091. }
  1092. if (!$cfg['keep']['skip']) {
  1093. @unlink($test_skipif);
  1094. }
  1095. return 'SKIPPED';
  1096. }
  1097. if (!strncasecmp('info', ltrim($output), 4)) {
  1098. if (preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) {
  1099. $info = &quot; (info: $m[1])&quot;;
  1100. }
  1101. }
  1102. if (!strncasecmp('warn', ltrim($output), 4)) {
  1103. if (preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) {
  1104. $warn = true; /* only if there is a reason */
  1105. $info = &quot; (warn: $m[1])&quot;;
  1106. }
  1107. }
  1108. }
  1109. }
  1110. if (@count($section_text['REDIRECTTEST']) == 1) {
  1111. $test_files = array();
  1112. $IN_REDIRECT = eval($section_text['REDIRECTTEST']);
  1113. $IN_REDIRECT['via'] = &quot;via [$shortname]\n\t&quot;;
  1114. $IN_REDIRECT['dir'] = realpath(dirname($file));
  1115. $IN_REDIRECT['prefix'] = trim($section_text['TEST']);
  1116. if (@count($IN_REDIRECT['TESTS']) == 1) {
  1117. if (is_array($org_file)) {
  1118. $test_files[] = $org_file[1];
  1119. } else {
  1120. $GLOBALS['test_files'] = $test_files;
  1121. find_files($IN_REDIRECT['TESTS']);
  1122. foreach($GLOBALS['test_files'] as $f) {
  1123. $test_files[] = array($f, $file);
  1124. }
  1125. }
  1126. $test_cnt += count($test_files) - 1;
  1127. $test_idx--;
  1128. show_redirect_start($IN_REDIRECT['TESTS'], $tested, $tested_file);
  1129. // set up environment
  1130. $redirenv = array_merge($environment, $IN_REDIRECT['ENV']);
  1131. $redirenv['REDIR_TEST_DIR'] = realpath($IN_REDIRECT['TESTS']) . DIRECTORY_SEPARATOR;
  1132. usort($test_files, &quot;test_sort&quot;);
  1133. run_all_tests($test_files, $redirenv, $tested);
  1134. show_redirect_ends($IN_REDIRECT['TESTS'], $tested, $tested_file);
  1135. // a redirected test never fails
  1136. $IN_REDIRECT = false;
  1137. return 'REDIR';
  1138. } else {
  1139. $bork_info = &quot;Redirect info must contain exactly one TEST string to be used as redirect directory.&quot;;
  1140. show_result(&quot;BORK&quot;, $bork_info, '', $temp_filenames);
  1141. $PHP_FAILED_TESTS['BORKED'][] = array (
  1142. 'name' =&gt; $file,
  1143. 'test_name' =&gt; '',
  1144. 'output' =&gt; '',
  1145. 'diff' =&gt; '',
  1146. 'info' =&gt; &quot;$bork_info [$file]&quot;,
  1147. 'unicode'=&gt; $unicode_semantics,
  1148. );
  1149. }
  1150. }
  1151. if (is_array($org_file) || @count($section_text['REDIRECTTEST']) == 1) {
  1152. if (is_array($org_file)) $file = $org_file[0];
  1153. $bork_info = &quot;Redirected test did not contain redirection info&quot;;
  1154. show_result(&quot;BORK&quot;, $bork_info, '', $temp_filenames);
  1155. $PHP_FAILED_TESTS['BORKED'][] = array (
  1156. 'name' =&gt; $file,
  1157. 'test_name' =&gt; '',
  1158. 'output' =&gt; '',
  1159. 'diff' =&gt; '',
  1160. 'info' =&gt; &quot;$bork_info [$file]&quot;,
  1161. );
  1162. //$test_cnt -= 1; // Only if is_array($org_file) ?
  1163. //$test_idx--;
  1164. return 'BORKED';
  1165. }
  1166. // We've satisfied the preconditions - run the test!
  1167. if ($cfg['show']['php']) {
  1168. echo &quot;\n========TEST========\n&quot;;
  1169. echo $section_text['FILE'];
  1170. echo &quot;========DONE========\n&quot;;
  1171. }
  1172. save_text($test_file, $section_text['FILE'], $temp_file);
  1173. if (array_key_exists('GET', $section_text)) {
  1174. $query_string = trim($section_text['GET']);
  1175. } else {
  1176. $query_string = '';
  1177. }
  1178. $env['REDIRECT_STATUS'] = '1';
  1179. $env['QUERY_STRING'] = $query_string;
  1180. $env['PATH_TRANSLATED'] = $test_file;
  1181. $env['SCRIPT_FILENAME'] = $test_file;
  1182. if (array_key_exists('COOKIE', $section_text)) {
  1183. $env['HTTP_COOKIE'] = trim($section_text['COOKIE']);
  1184. } else {
  1185. $env['HTTP_COOKIE'] = '';
  1186. }
  1187. $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : '';
  1188. if (array_key_exists('POST_RAW', $section_text) &amp;&amp; !empty($section_text['POST_RAW'])) {
  1189. $post = trim($section_text['POST_RAW']);
  1190. $raw_lines = explode(&quot;\n&quot;, $post);
  1191. $request = '';
  1192. foreach ($raw_lines as $line) {
  1193. if (empty($env['CONTENT_TYPE']) &amp;&amp; preg_match('/^Content-Type:(.*)/i', $line, $res)) {
  1194. $env['CONTENT_TYPE'] = trim(str_replace(&quot;\r&quot;, '', $res[1]));
  1195. continue;
  1196. }
  1197. $request .= $line . &quot;\n&quot;;
  1198. }
  1199. $env['CONTENT_LENGTH'] = strlen($request);
  1200. $env['REQUEST_METHOD'] = 'POST';
  1201. if (empty($request)) {
  1202. return 'BORKED';
  1203. }
  1204. save_text($tmp_post, $request);
  1205. $cmd = &quot;$php$pass_options$ini_settings -f \&quot;$test_file\&quot; 2&gt;&amp;1 &lt; $tmp_post&quot;;
  1206. } elseif (array_key_exists('POST', $section_text) &amp;&amp; !empty($section_text['POST'])) {
  1207. $post = trim($section_text['POST']);
  1208. if (array_key_exists('GZIP_POST', $section_text) &amp;&amp; function_exists('gzencode')) {
  1209. $post = gzencode($post, 9, FORCE_GZIP);
  1210. $env['HTTP_CONTENT_ENCODING'] = 'gzip';
  1211. } else if (array_key_exists('DEFLATE_POST', $section_text) &amp;&amp; function_exists('gzcompress')) {
  1212. $post = gzcompress($post, 9);
  1213. $env['HTTP_CONTENT_ENCODING'] = 'deflate';
  1214. }
  1215. save_text($tmp_post, $post);
  1216. $content_length = strlen($post);
  1217. $env['REQUEST_METHOD'] = 'POST';
  1218. $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded';
  1219. $env['CONTENT_LENGTH'] = $content_length;
  1220. $cmd = &quot;$php$pass_options$ini_settings -f \&quot;$test_file\&quot; 2&gt;&amp;1 &lt; $tmp_post&quot;;
  1221. } else {
  1222. $env['REQUEST_METHOD'] = 'GET';
  1223. $env['CONTENT_TYPE'] = '';
  1224. $env['CONTENT_LENGTH'] = '';
  1225. $cmd = &quot;$php$pass_options$ini_settings -f \&quot;$test_file\&quot; $args 2&gt;&amp;1&quot;;
  1226. }
  1227. if ($leak_check) {
  1228. $env['USE_ZEND_ALLOC'] = '0';
  1229. $cmd = &quot;valgrind -q --tool=memcheck --trace-children=yes --log-file-exactly=$memcheck_filename $cmd&quot;;
  1230. } else {
  1231. $env['USE_ZEND_ALLOC'] = '1';
  1232. }
  1233. if ($DETAILED) echo &quot;
  1234. CONTENT_LENGTH = &quot; . $env['CONTENT_LENGTH'] . &quot;
  1235. CONTENT_TYPE = &quot; . $env['CONTENT_TYPE'] . &quot;
  1236. PATH_TRANSLATED = &quot; . $env['PATH_TRANSLATED'] . &quot;
  1237. QUERY_STRING = &quot; . $env['QUERY_STRING'] . &quot;
  1238. REDIRECT_STATUS = &quot; . $env['REDIRECT_STATUS'] . &quot;
  1239. REQUEST_METHOD = &quot; . $env['REQUEST_METHOD'] . &quot;
  1240. SCRIPT_FILENAME = &quot; . $env['SCRIPT_FILENAME'] . &quot;
  1241. HTTP_COOKIE = &quot; . $env['HTTP_COOKIE'] . &quot;
  1242. COMMAND $cmd
  1243. &quot;;
  1244. $out = system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null);
  1245. if (array_key_exists('CLEAN', $section_text) &amp;&amp; (!$no_clean || $cfg['keep']['clean'])) {
  1246. if (trim($section_text['CLEAN'])) {
  1247. if ($cfg['show']['clean']) {
  1248. echo &quot;\n========CLEAN=======\n&quot;;
  1249. echo $section_text['CLEAN'];
  1250. echo &quot;========DONE========\n&quot;;
  1251. }
  1252. save_text($test_clean, trim($section_text['CLEAN']), $temp_clean);
  1253. if (!$no_clean) {
  1254. $clean_params = array();
  1255. settings2array($ini_overwrites,$clean_params);
  1256. settings2params($clean_params);
  1257. $extra = substr(PHP_OS, 0, 3) !== &quot;WIN&quot; ?
  1258. &quot;unset REQUEST_METHOD; unset QUERY_STRING; unset PATH_TRANSLATED; unset SCRIPT_FILENAME; unset REQUEST_METHOD;&quot;: &quot;&quot;;
  1259. system_with_timeout(&quot;$extra $php $pass_options -q $clean_params $test_clean&quot;, $env);
  1260. }
  1261. if (!$cfg['keep']['clean']) {
  1262. @unlink($test_clean);
  1263. }
  1264. }
  1265. }
  1266. @unlink($tmp_post);
  1267. $leaked = false;
  1268. $passed = false;
  1269. if ($leak_check) { // leak check
  1270. $leaked = @filesize($memcheck_filename) &gt; 0;
  1271. if (!$leaked) {
  1272. @unlink($memcheck_filename);
  1273. }
  1274. }
  1275. // Does the output match what is expected?
  1276. $output = str_replace(&quot;\r\n&quot;, &quot;\n&quot;, trim($out));
  1277. /* when using CGI, strip the headers from the output */
  1278. $headers = &quot;&quot;;
  1279. if (isset($old_php) &amp;&amp; preg_match(&quot;/^(.*?)\r?\n\r?\n(.*)/s&quot;, $out, $match)) {
  1280. $output = trim($match[2]);
  1281. $rh = preg_split(&quot;/[\n\r]+/&quot;,$match[1]);
  1282. $headers = array();
  1283. foreach ($rh as $line) {
  1284. if (strpos($line, ':')!==false) {
  1285. $line = explode(':', $line, 2);
  1286. $headers[trim($line[0])] = trim($line[1]);
  1287. }
  1288. }
  1289. }
  1290. $failed_headers = false;
  1291. if (isset($section_text['EXPECTHEADERS'])) {
  1292. $want = array();
  1293. $wanted_headers = array();
  1294. $lines = preg_split(&quot;/[\n\r]+/&quot;,$section_text['EXPECTHEADERS']);
  1295. foreach($lines as $line) {
  1296. if (strpos($line, ':') !== false) {
  1297. $line = explode(':', $line, 2);
  1298. $want[trim($line[0])] = trim($line[1]);
  1299. $wanted_headers[] = trim($line[0]) . ': ' . trim($line[1]);
  1300. }
  1301. }
  1302. $org_headers = $headers;
  1303. $headers = array();
  1304. $output_headers = array();
  1305. foreach($want as $k =&gt; $v) {
  1306. if (isset($org_headers[$k])) {
  1307. $headers = $org_headers[$k];
  1308. $output_headers[] = $k . ': ' . $org_headers[$k];
  1309. }
  1310. if (!isset($org_headers[$k]) || $org_headers[$k] != $v) {
  1311. $failed_headers = true;
  1312. }
  1313. }
  1314. ksort($wanted_headers);
  1315. $wanted_headers = join(&quot;\n&quot;, $wanted_headers);
  1316. ksort($output_headers);
  1317. $output_headers = join(&quot;\n&quot;, $output_headers);
  1318. }
  1319. if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) {
  1320. if (isset($section_text['EXPECTF'])) {
  1321. $wanted = trim($section_text['EXPECTF']);
  1322. } else {
  1323. $wanted = trim($section_text['EXPECTREGEX']);
  1324. }
  1325. $wanted_re = preg_replace('/\r\n/',&quot;\n&quot;,$wanted);
  1326. if (isset($section_text['EXPECTF'])) {
  1327. $wanted_re = preg_quote($wanted_re, '/');
  1328. // Stick to basics
  1329. $wanted_re = str_replace(&quot;%e&quot;, '\\' . DIRECTORY_SEPARATOR, $wanted_re);
  1330. $wanted_re = str_replace(&quot;%s&quot;, &quot;.+?&quot;, $wanted_re); //not greedy
  1331. $wanted_re = str_replace(&quot;%w&quot;, &quot;\s*&quot;, $wanted_re);
  1332. $wanted_re = str_replace(&quot;%i&quot;, &quot;[+\-]?[0-9]+&quot;, $wanted_re);
  1333. $wanted_re = str_replace(&quot;%d&quot;, &quot;[0-9]+&quot;, $wanted_re);
  1334. $wanted_re = str_replace(&quot;%x&quot;, &quot;[0-9a-fA-F]+&quot;, $wanted_re);
  1335. $wanted_re = str_replace(&quot;%f&quot;, &quot;[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?&quot;, $wanted_re);
  1336. $wanted_re = str_replace(&quot;%c&quot;, &quot;.&quot;, $wanted_re);
  1337. // %f allows two points &quot;-.0.0&quot; but that is the best *simple* expression
  1338. }
  1339. /* DEBUG YOUR REGEX HERE
  1340. var_dump($wanted_re);
  1341. print(str_repeat('=', 80) . &quot;\n&quot;);
  1342. var_dump($output);
  1343. */
  1344. if (preg_match(&quot;/^$wanted_re\$/s&quot;, $output)) {
  1345. $passed = true;
  1346. if (!$cfg['keep']['php']) {
  1347. @unlink($test_file);
  1348. }
  1349. if (isset($old_php)) {
  1350. $php = $old_php;
  1351. }
  1352. if (!$leaked &amp;&amp; !$failed_headers) {
  1353. show_result(&quot;PASS&quot;, $tested, $tested_file, '', $temp_filenames);
  1354. return 'PASSED';
  1355. }
  1356. }
  1357. } else {
  1358. $wanted = trim($section_text['EXPECT']);
  1359. $wanted = preg_replace('/\r\n/',&quot;\n&quot;,$wanted);
  1360. // compare and leave on success
  1361. if (!strcmp($output, $wanted)) {
  1362. $passed = true;
  1363. if (!$cfg['keep']['php']) {
  1364. @unlink($test_file);
  1365. }
  1366. if (isset($old_php)) {
  1367. $php = $old_php;
  1368. }
  1369. if (!$leaked &amp;&amp; !$failed_headers) {
  1370. show_result(&quot;PASS&quot;, $tested, $tested_file, '', $temp_filenames);
  1371. return 'PASSED';
  1372. }
  1373. }
  1374. $wanted_re = NULL;
  1375. }
  1376. // Test failed so we need to report details.
  1377. if ($failed_headers) {
  1378. $passed = false

Large files files are truncated, but you can click here to view the full file