├── robots.txt ├── regtests ├── test │ ├── ideals │ │ ├── testclassfunc.out │ │ ├── recurse.out │ │ ├── testarray.out │ │ ├── testobj.out │ │ ├── test_class_inheritance.out │ │ ├── 4254.out │ │ ├── arraysort.out │ │ ├── testarray2.out │ │ ├── testdbaseaddrec.out │ │ └── testscanf.out │ ├── actuals │ │ ├── testclassfunc.out │ │ ├── recurse.out │ │ ├── testarray.out │ │ ├── testobj.out │ │ ├── test_class_inheritance.out │ │ ├── 4254.out │ │ ├── arraysort.out │ │ ├── testarray2.out │ │ └── testscanf.out │ ├── suite │ │ └── bin │ │ │ ├── testarray2.php │ │ │ ├── testclassfunc.php │ │ │ ├── recurse.php │ │ │ ├── testarray.php │ │ │ ├── 4254.php │ │ │ ├── test_class_inheritance.php │ │ │ ├── testobj.php │ │ │ ├── testdbaseaddrec.php │ │ │ ├── arraysort.php │ │ │ └── testscanf.php │ └── input │ │ └── scan_cases ├── maketests ├── runtests └── README ├── .htaccess ├── favicon.ico ├── gfx ├── github.ico ├── line_1.jpg ├── logo_qa.jpg ├── php-logo.gif ├── spacer.gif ├── submit.gif ├── testfest_big.png └── testfest_small_08.png ├── howto_phpt.png ├── reports ├── bug.png ├── home.png ├── detail.png ├── report.png ├── sample.txt ├── phpsource.png ├── sorttable.js ├── todo.txt ├── index.php ├── convert.php ├── README ├── details.php ├── parse_ciqa.php ├── viewreports.php ├── reportsfunctions.php ├── test-insert.php └── run_tests.php ├── howto_phpunit.png ├── .gitignore ├── .gitmodules ├── README.md ├── sample_tests ├── file012.php ├── skipif2.php ├── sample012.php ├── sample011.php ├── sample009.php ├── sample016.php ├── sample013.php ├── sample002.php ├── capture_stdio_1.php ├── capture_stdio_2.php ├── sample026.php ├── xfailif.php ├── extensions.php ├── flaky.php ├── capture_stdio_3.php ├── sample023.php ├── phpdbg_1.php ├── sample010.php ├── sample018.php ├── sample020.php ├── clean.php ├── skipif.php ├── conflicts_1.php ├── sample024.php ├── sample008.php ├── sample003.php ├── sample014.php ├── flakyif.php ├── sample021.php ├── sample006.php ├── sample022.php ├── sample019.php ├── sample005.php ├── sample007.php ├── sample017.php ├── sample001.php └── sample025.php ├── include ├── functions.php └── release-qa.php ├── howto_phpunit.php ├── api.php ├── list_builds.php ├── howto_phpt.php ├── pftt.php ├── rc.php ├── howtohelp.php ├── expectf_details.php ├── index.php ├── projects.php ├── pftt_report.php ├── running-tests.php └── handling-bugs.php /robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: / 3 | -------------------------------------------------------------------------------- /regtests/test/ideals/testclassfunc.out: -------------------------------------------------------------------------------- 1 | Hey there! 2 | -------------------------------------------------------------------------------- /regtests/test/actuals/testclassfunc.out: -------------------------------------------------------------------------------- 1 | Hey there! 2 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | php_value include_path .:./include:../include 2 | -------------------------------------------------------------------------------- /regtests/test/actuals/recurse.out: -------------------------------------------------------------------------------- 1 | $sum=6.2096002783282E+62 2 | -------------------------------------------------------------------------------- /regtests/test/ideals/recurse.out: -------------------------------------------------------------------------------- 1 | $sum=6.2096002783282E+62 2 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/favicon.ico -------------------------------------------------------------------------------- /gfx/github.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/github.ico -------------------------------------------------------------------------------- /gfx/line_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/line_1.jpg -------------------------------------------------------------------------------- /gfx/logo_qa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/logo_qa.jpg -------------------------------------------------------------------------------- /gfx/php-logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/php-logo.gif -------------------------------------------------------------------------------- /gfx/spacer.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/spacer.gif -------------------------------------------------------------------------------- /gfx/submit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/submit.gif -------------------------------------------------------------------------------- /howto_phpt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/howto_phpt.png -------------------------------------------------------------------------------- /regtests/test/ideals/testarray.out: -------------------------------------------------------------------------------- 1 | This is a small test.... 2 | 1049895000 3 | -------------------------------------------------------------------------------- /reports/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/reports/bug.png -------------------------------------------------------------------------------- /reports/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/reports/home.png -------------------------------------------------------------------------------- /howto_phpunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/howto_phpunit.png -------------------------------------------------------------------------------- /regtests/maketests: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/regtests/maketests -------------------------------------------------------------------------------- /regtests/runtests: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/regtests/runtests -------------------------------------------------------------------------------- /regtests/test/actuals/testarray.out: -------------------------------------------------------------------------------- 1 | This is a small test.... 2 | 1049895000 3 | -------------------------------------------------------------------------------- /reports/detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/reports/detail.png -------------------------------------------------------------------------------- /reports/report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/reports/report.png -------------------------------------------------------------------------------- /reports/sample.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/reports/sample.txt -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | reports/db/*.sqlite 2 | reports/db/*.cache 3 | pftt-reports/* 4 | shared/ 5 | -------------------------------------------------------------------------------- /gfx/testfest_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/testfest_big.png -------------------------------------------------------------------------------- /reports/phpsource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/reports/phpsource.png -------------------------------------------------------------------------------- /reports/sorttable.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/reports/sorttable.js -------------------------------------------------------------------------------- /regtests/test/actuals/testobj.out: -------------------------------------------------------------------------------- 1 | foobar 2 | 3 | barbara 4 | foobar 5 | 1 6 | 1 7 | 1 8 | -------------------------------------------------------------------------------- /regtests/test/ideals/testobj.out: -------------------------------------------------------------------------------- 1 | foobar 2 | 3 | barbara 4 | foobar 5 | 1 6 | 1 7 | 1 8 | -------------------------------------------------------------------------------- /gfx/testfest_small_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/php/web-qa/HEAD/gfx/testfest_small_08.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "shared"] 2 | path = shared 3 | url = git@github.com:php/web-shared.git 4 | -------------------------------------------------------------------------------- /regtests/test/suite/bin/testarray2.php: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 |
11 |

Sample Test: file012.inc

12 |

Back to "PHPT Test File Layout"

13 |
<?php
14 |   echo "hello world\n";
15 | ?>
16 | 
17 |

Back to "PHPT Test File Layout"

18 |
19 | 20 | 23 | -------------------------------------------------------------------------------- /reports/todo.txt: -------------------------------------------------------------------------------- 1 | Reports per week : 2 | SELECT VERSION,COUNT(id), YEAR(DATE),WEEK(DATE) FROM reports 3 | GROUP BY VERSION,YEAR(DATE),WEEK(DATE) 4 | 5 | If we have time : graph to see reports sent by version and by date 6 | 7 | use https://svn.php.net/viewvc/web/php/trunk/include/version.inc?view=co 8 | 9 | ----------------------------------------- 10 | Improve documentation functions, syntax, etc. 11 | ----------------------------------------- 12 | 13 | ------------------- 14 | Vote : should env config in /reports/ be hidden to everyone except logged in php accounts ? 15 | 2) blacklist robots with meta ? 16 | ------------------- 17 | -------------------------------------------------------------------------------- /sample_tests/skipif2.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: skipif2.inc

12 |

Back to "PHPT Test File Layout"

13 |
<?php
14 |   if (!extension_loaded('soap')) die('skip soap extension not available');
15 | ?>
16 | 
17 |

Back to "PHPT Test File Layout"

18 |
19 | 20 | 23 | -------------------------------------------------------------------------------- /regtests/test/suite/bin/4254.php: -------------------------------------------------------------------------------- 1 | 26 | -------------------------------------------------------------------------------- /sample_tests/sample012.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample012.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | sample test for file_external
15 | --FILE_EXTERNAL--
16 | files/file012.inc
17 | --EXPECT--
18 | hello world
19 | 
20 |

Back to "PHPT Test File Layout"

21 |
22 | 23 | 26 | -------------------------------------------------------------------------------- /regtests/test/suite/bin/test_class_inheritance.php: -------------------------------------------------------------------------------- 1 | class_name; 11 | } 12 | }; 13 | 14 | 15 | class ChildClass { 16 | var $class_name = "ChildClass"; 17 | 18 | function ChildClass($value, $new_value) { 19 | BaseClass::BaseClass($value); 20 | print "new value is '$new_value'\n"; 21 | } 22 | function MyClassName($a_value) { 23 | return BaseClass::MyClassName()." and the value is '$a_value'"; 24 | } 25 | }; 26 | 27 | 28 | $obj = new ChildClass("Test", "Another test"); 29 | print $obj->MyClassName("not interesting"); -------------------------------------------------------------------------------- /regtests/test/suite/bin/testobj.php: -------------------------------------------------------------------------------- 1 | initialized = 1; 7 | } 8 | }; 9 | 10 | class barbara extends foobar { 11 | 12 | }; 13 | 14 | $name = "foobar"; 15 | $foo = new $name; // or die("Unable to construct foobar\n"); 16 | //print $foo->initialized; 17 | 18 | $boo = new barbara; 19 | print get_class($foo).endl; 20 | print get_parent_class($foo).endl; 21 | print get_class($boo).endl; 22 | print get_parent_class($boo).endl; 23 | print method_exists($foo,"foobar").endl; 24 | print method_exists($boo,"foobar").endl; 25 | print method_exists($boo,"barbara").endl; 26 | //$word = new COm("word.application"); 27 | //$word->visible = true; 28 | //sleep(5); 29 | //$word->quit(); 30 | -------------------------------------------------------------------------------- /sample_tests/sample011.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample011.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Bug #35382 (Comment in end of file produces fatal error)
15 | --FILEEOF--
16 | <?php
17 | eval("echo 'Hello'; // comment");
18 | echo " World";
19 | //last line comment
20 | --EXPECTF--
21 | Hello World
22 | 
23 |

Back to "PHPT Test File Layout"

24 |
25 | 26 | 29 | -------------------------------------------------------------------------------- /sample_tests/sample009.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample009.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | STDIN input
15 | --FILE--
16 | <?php
17 | var_dump(stream_get_contents(STDIN));
18 | ?>
19 | --STDIN--
20 | fooBar
21 | use this to input some thing to the php script
22 | --EXPECT--
23 | string(54) "fooBar
24 | use this to input some thing to the php script
25 | "
26 | 
27 |

Back to "PHPT Test File Layout"

28 |
29 | 30 | 33 | -------------------------------------------------------------------------------- /sample_tests/sample016.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample016.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Test get variables with CGI binary
15 | --GET--
16 | hello=World&goodbye=MrChips
17 | --CGI--
18 | --FILE--
19 | <?php
20 | var_dump($_GET);
21 | ?>
22 | --EXPECT--
23 | array(2) {
24 |   ["hello"]=>
25 |   string(5) "World"
26 |   ["goodbye"]=>
27 |   string(7) "MrChips"
28 | }
29 | 
30 |

Back to "PHPT Test File Layout"

31 |
32 | 33 | 36 | -------------------------------------------------------------------------------- /sample_tests/sample013.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample013.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | SQLite2
15 | --SKIPIF--
16 | <?php # vim:ft=php
17 | if (!extension_loaded('pdo') || !extension_loaded('sqlite')) print 'skip'; ?>
18 | --REDIRECTTEST--
19 | return array(
20 |   'ENV' => array(
21 |       'PDOTEST_DSN' => 'sqlite2::memory:'
22 |     ),
23 |   'TESTS' => 'ext/pdo/tests'
24 |   );
25 | 
26 |

Back to "PHPT Test File Layout"

27 |
28 | 29 | 32 | -------------------------------------------------------------------------------- /sample_tests/sample002.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample002.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Test receipt of cookie data.
15 | --CREDITS--
16 | Zoe Slattery zoe@php.net
17 | # TestFest Munich 2009-05-19
18 | --COOKIE--
19 | hello=World;goodbye=MrChips
20 | --FILE--
21 | <?php
22 | var_dump($_COOKIE);
23 | ?>
24 | --EXPECT--
25 | array(2) {
26 |   ["hello"]=>
27 |   string(5) "World"
28 |   ["goodbye"]=>
29 |   string(7) "MrChips"
30 | }
31 | 
32 |

Back to "PHPT Test File Layout"

33 |
34 | 35 | 38 | -------------------------------------------------------------------------------- /sample_tests/capture_stdio_1.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: capture_stdio_1.phpt

12 |

Back to "PHPT Test File Layout"

13 |
14 | --TEST--
15 | Test covering the I/O stdin and stdout streams.
16 | --DESCRIPTION--
17 | This tests checks if the output of stdin and stdout I/O streams match the
18 | expected content.
19 | --CAPTURE_STDIO--
20 | STDIN STDERR
21 | --FILE--
22 | <?php
23 | echo "Hello, world. This is sent to the stdout I/O stream\n";
24 | fwrite(STDERR, "This is error sent to the stderr I/O stream\n");
25 | ?>
26 | --EXPECT--
27 | This is error sent to the stderr I/O stream
28 | 
29 |

Back to "PHPT Test File Layout"

30 |
31 | 32 | 35 | -------------------------------------------------------------------------------- /sample_tests/capture_stdio_2.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: capture_stdio_2.phpt

12 |

Back to "PHPT Test File Layout"

13 |
14 | --TEST--
15 | Test covering the I/O stdin and stderr streams.
16 | --DESCRIPTION--
17 | This tests checks if the output of stdin and stderr I/O streams match the
18 | expected content.
19 | --CAPTURE_STDIO--
20 | STDIN STDOUT
21 | --FILE--
22 | <?php
23 | echo "Hello, world. This is sent to the stdout I/O stream\n";
24 | fwrite(STDERR, "This is error sent to the stderr I/O stream\n");
25 | ?>
26 | --EXPECT--
27 | Hello, world. This is sent to the stdout I/O stream
28 | 
29 |

Back to "PHPT Test File Layout"

30 |
31 | 32 | 35 | -------------------------------------------------------------------------------- /sample_tests/sample026.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample027.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | SPL: ArrayIterator implementing RecursiveIterator
15 | --FILE--
16 | <?php
17 | 
18 | $array = array(1, 2 => array(21, 22 => array(221, 222), 23 => array(231)), 3);
19 | 
20 | $dir = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), RecursiveIteratorIterator::LEAVES_ONLY);
21 | 
22 | foreach ($dir as $file) {
23 | 	print "$file\n";
24 | }
25 | 
26 | ?>
27 | ===DONE===
28 | <?php exit(0); ?>
29 | --EXPECT--
30 | 1
31 | 21
32 | 221
33 | 222
34 | 231
35 | 3
36 | 
37 |

Back to "PHPT Test File Layout"

38 |
39 | 40 | 43 | -------------------------------------------------------------------------------- /sample_tests/xfailif.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: skipif2.inc

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Handling of errors during linking
15 | --INI--
16 | opcache.enable=1
17 | opcache.enable_cli=1
18 | opcache.optimization_level=-1
19 | opcache.preload={PWD}/preload_inheritance_error_ind.inc
20 | --SKIPIF--
21 | <?php
22 | require_once('skipif.inc');
23 | if (getenv('SKIP_ASAN')) die('xfail Startup failure leak');
24 | ?>
25 | --FILE--
26 | <?php
27 | echo "Foobar\n";
28 | ?>
29 | --EXPECTF--
30 | Fatal error: Declaration of B::foo($bar) must be compatible with A::foo() in %spreload_inheritance_error.inc on line 8
31 | 
32 |

Back to "PHPT Test File Layout"

33 |
34 | 35 | 38 | -------------------------------------------------------------------------------- /reports/index.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |

QA reports and test data are generated using two different tools, run-tests.php and PFTT:

13 | 14 |

15 | run-tests.php The standard tool for running PHPT tests against PHP core on the command-line (CLI scenario). Whenever users build PHP for install, they should run `make test`, which runs run-test.php on their build. 16 |

17 | 18 |

19 | PFTT 20 | 21 | The Php Full Test Tool (PFTT) is a cross-platform test tool for PHP Core and Applications developed by Microsoft, primarily for PHP on Microsoft Windows, Windows Server and Azure. 22 | PFTT covers the PHP ecosystem and is designed for convenience, thoroughness and speed: PFTT can run PHPT and PhpUnit tests across a variety of scenarios, including on Apache. 23 | 24 |

25 | 29 | -------------------------------------------------------------------------------- /sample_tests/extensions.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: extensions.phpt

12 |

Back to "PHPT Test File Layout"

13 | 14 |
--TEST--
15 | phpt EXTENSIONS directive with shared extensions
16 | --DESCRIPTION--
17 | This test covers the presence of some loaded extensions with a list of additional
18 | extensions to be loaded when running test.
19 | --EXTENSIONS--
20 | curl
21 | imagick
22 | tokenizer
23 | --FILE--
24 | <?php
25 | var_dump(extension_loaded('curl'));
26 | var_dump(extension_loaded('imagick'));
27 | var_dump(extension_loaded('tokenizer'));
28 | ?>
29 | --EXPECT--
30 | bool(true)
31 | bool(true)
32 | bool(true)
33 | 
34 | 35 |

Back to "PHPT Test File Layout"

36 |
37 | 38 | 41 | -------------------------------------------------------------------------------- /sample_tests/flaky.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample001.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Test hrtime() aligns with microtime()
15 | --FLAKY--
16 | This test frequently fails in CI
17 | --FILE--
18 | <?php
19 | 
20 | $m0 = microtime(true);
21 | $h0 = hrtime(true);
22 | for ($i = 0; $i < 1024*1024; $i++);
23 | $h1 = hrtime(true);
24 | $m1 = microtime(true);
25 | 
26 | $d0 = ($m1 - $m0)*1000000000.0;
27 | $d1 = $h1 - $h0;
28 | 
29 | /* Relative uncertainty. */
30 | $d = abs($d0 - $d1)/$d1;
31 | 
32 | if ($d > 0.05) {
33 |     print "FAIL, $d";
34 | } else {
35 |     print "OK, $d";
36 | }
37 | 
38 | ?>
39 | --EXPECTF--
40 | OK, %f
41 | 
42 |

Back to "PHPT Test File Layout"

43 |
44 | 45 | 48 | -------------------------------------------------------------------------------- /sample_tests/capture_stdio_3.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: capture_stdio_1.phpt

12 |

Back to "PHPT Test File Layout"

13 |
14 | --TEST--
15 | Test covering the all standard I/O streams.
16 | --DESCRIPTION--
17 | This tests checks if the output of stdin, stdout and stderr I/O streams match
18 | the expected content.
19 | --CAPTURE_STDIO--
20 | STDIN STDOUT STDERR
21 | --FILE--
22 | <?php
23 | echo "Hello, world. This is sent to the stdout I/O stream\n";
24 | fwrite(STDERR, "This is error sent to the stderr I/O stream\n");
25 | ?>
26 | --EXPECT--
27 | Hello, world. This is sent to the stdout I/O stream
28 | This is error sent to the stderr I/O stream
29 | 
30 |

Back to "PHPT Test File Layout"

31 |
32 | 33 | 36 | -------------------------------------------------------------------------------- /sample_tests/sample023.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample023.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Bug #23894 (sprintf() decimal specifiers problem)
15 | --FILE--
16 | <?php
17 | $a = -12.3456;
18 | $test = sprintf("%04d", $a);
19 | var_dump($test, bin2hex($test));
20 | $test = sprintf("% 13u", $a);
21 | var_dump($test, bin2hex($test));
22 | ?>
23 | --EXPECTREGEX--
24 | string\(4\) \"-012\"
25 | string\(8\) \"2d303132\"
26 | (string\(13\) \"   4294967284\"|string\(20\) \"18446744073709551604\")
27 | (string\(26\) \"20202034323934393637323834\"|string\(40\) \"3138343436373434303733373039353531363034\")
28 | 
29 |

Back to "PHPT Test File Layout"

30 |
31 | 32 | 35 | -------------------------------------------------------------------------------- /sample_tests/phpdbg_1.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: phpdbg_1.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Test deleting breakpoints
15 | --PHPDBG--
16 | b 4
17 | b del 0
18 | b 5
19 | r
20 | b del 1
21 | r
22 | y
23 | q
24 | --EXPECTF--
25 | [Successful compilation of %s]
26 | prompt> [Breakpoint #0 added at %s:4]
27 | prompt> [Deleted breakpoint #0]
28 | prompt> [Breakpoint #1 added at %s:5]
29 | prompt> 12
30 | [Breakpoint #1 at %s:5, hits: 1]
31 | >00005: echo $i++;
32 |  00006: echo $i++;
33 |  00007: 
34 | prompt> [Deleted breakpoint #1]
35 | prompt> Do you really want to restart execution? (type y or n): 1234
36 | [Script ended normally]
37 | prompt> 
38 | --FILE--
39 | <?php
40 | $i = 1;
41 | echo $i++;
42 | echo $i++;
43 | echo $i++;
44 | echo $i++;
45 | 
46 |

Back to "PHPT Test File Layout"

47 |
48 | 49 | 52 | -------------------------------------------------------------------------------- /sample_tests/sample010.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample010.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | getopt#005 (Required values)
15 | --ARGS--
16 | --arg value --arg=value -avalue -a=value -a value
17 | --INI--
18 | register_argc_argv=On
19 | variables_order=GPS
20 | --FILE--
21 | <?php
22 |   var_dump(getopt("a:", array("arg:")));
23 | ?>
24 | --EXPECT--
25 | array(2) {
26 |   ["arg"]=>
27 |   array(2) {
28 |     [0]=>
29 |     string(5) "value"
30 |     [1]=>
31 |     string(5) "value"
32 |   }
33 |   ["a"]=>
34 |   array(3) {
35 |     [0]=>
36 |     string(5) "value"
37 |     [1]=>
38 |     string(5) "value"
39 |     [2]=>
40 |     string(5) "value"
41 |   }
42 | }
43 | 
44 | 
45 | 
46 |

Back to "PHPT Test File Layout"

47 |
48 | 49 | 52 | -------------------------------------------------------------------------------- /sample_tests/sample018.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample018.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Phar front controller rewrite access denied [cache_list]
15 | --INI--
16 | default_charset=UTF-8
17 | phar.cache_list={PWD}/frontcontroller10.php
18 | --SKIPIF--
19 | <?php if (!extension_loaded("phar")) die("skip"); ?>
20 | --ENV--
21 | SCRIPT_NAME=/frontcontroller10.php
22 | REQUEST_URI=/frontcontroller10.php/hi
23 | PATH_INFO=/hi
24 | --FILE_EXTERNAL--
25 | files/frontcontroller4.phar
26 | --EXPECTHEADERS--
27 | Content-type: text/html; charset=UTF-8
28 | Status: 403 Access Denied
29 | --EXPECT--
30 | <html>
31 |  <head>
32 |   <title>Access Denied</title>
33 |  </head>
34 |  <body>
35 |   <h1>403 - File /hi Access Denied</h1>
36 |  </body>
37 | </html>
38 | 
39 |

Back to "PHPT Test File Layout"

40 |
41 | 42 | 45 | -------------------------------------------------------------------------------- /regtests/test/actuals/arraysort.out: -------------------------------------------------------------------------------- 1 | 0: 0 2 | 1: 1 3 | 2: 01 4 | 3: 02 5 | 4: 2 6 | 7 | 0: 02 8 | 1: 2 9 | 2: 1 10 | 3: 01 11 | 4: 0 12 | sort 13 | 0: 0 14 | 1: 1 15 | 2: 01 16 | 3: 2 17 | 4: 02 18 | 5: 03 19 | 6: 23 20 | 7: 044 21 | rsort 22 | 0: 044 23 | 1: 23 24 | 2: 03 25 | 3: 2 26 | 4: 02 27 | 5: 1 28 | 6: 01 29 | 7: 0 30 | asort 31 | 0: 0 32 | 1: 1 33 | 3: 01 34 | 2: 2 35 | 4: 02 36 | 5: 03 37 | 6: 23 38 | 7: 044 39 | arsort 40 | 7: 044 41 | 6: 23 42 | 5: 03 43 | 2: 2 44 | 4: 02 45 | 1: 1 46 | 3: 01 47 | 0: 0 48 | ksort 49 | 0: 0 50 | 1: 1 51 | 2: 2 52 | 3: 01 53 | 4: 02 54 | 5: 03 55 | 6: 23 56 | 7: 044 57 | sort 58 | 0: 044 59 | 1: 2luv3 60 | 2: Bill 61 | 3: Rob 62 | 4: able 63 | 5: ant 64 | 6: baker 65 | 7: charlie 66 | rsort 67 | 0: charlie 68 | 1: baker 69 | 2: ant 70 | 3: able 71 | 4: Rob 72 | 5: Bill 73 | 6: 2luv3 74 | 7: 044 75 | asort 76 | 7: 044 77 | 6: 2luv3 78 | 4: Bill 79 | 5: Rob 80 | 0: able 81 | 3: ant 82 | 1: baker 83 | 2: charlie 84 | arsort 85 | 2: charlie 86 | 1: baker 87 | 3: ant 88 | 0: able 89 | 5: Rob 90 | 4: Bill 91 | 6: 2luv3 92 | 7: 044 93 | ksort 94 | 0: able 95 | 1: baker 96 | 2: charlie 97 | 3: ant 98 | 4: Bill 99 | 5: Rob 100 | 6: 2luv3 101 | 7: 044 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /regtests/test/ideals/arraysort.out: -------------------------------------------------------------------------------- 1 | 0: 0 2 | 1: 1 3 | 2: 01 4 | 3: 02 5 | 4: 2 6 | 7 | 0: 02 8 | 1: 2 9 | 2: 1 10 | 3: 01 11 | 4: 0 12 | sort 13 | 0: 0 14 | 1: 1 15 | 2: 01 16 | 3: 2 17 | 4: 02 18 | 5: 03 19 | 6: 23 20 | 7: 044 21 | rsort 22 | 0: 044 23 | 1: 23 24 | 2: 03 25 | 3: 2 26 | 4: 02 27 | 5: 1 28 | 6: 01 29 | 7: 0 30 | asort 31 | 0: 0 32 | 1: 1 33 | 3: 01 34 | 2: 2 35 | 4: 02 36 | 5: 03 37 | 6: 23 38 | 7: 044 39 | arsort 40 | 7: 044 41 | 6: 23 42 | 5: 03 43 | 2: 2 44 | 4: 02 45 | 1: 1 46 | 3: 01 47 | 0: 0 48 | ksort 49 | 0: 0 50 | 1: 1 51 | 2: 2 52 | 3: 01 53 | 4: 02 54 | 5: 03 55 | 6: 23 56 | 7: 044 57 | sort 58 | 0: 044 59 | 1: 2luv3 60 | 2: Bill 61 | 3: Rob 62 | 4: able 63 | 5: ant 64 | 6: baker 65 | 7: charlie 66 | rsort 67 | 0: charlie 68 | 1: baker 69 | 2: ant 70 | 3: able 71 | 4: Rob 72 | 5: Bill 73 | 6: 2luv3 74 | 7: 044 75 | asort 76 | 7: 044 77 | 6: 2luv3 78 | 4: Bill 79 | 5: Rob 80 | 0: able 81 | 3: ant 82 | 1: baker 83 | 2: charlie 84 | arsort 85 | 2: charlie 86 | 1: baker 87 | 3: ant 88 | 0: able 89 | 5: Rob 90 | 4: Bill 91 | 6: 2luv3 92 | 7: 044 93 | ksort 94 | 0: able 95 | 1: baker 96 | 2: charlie 97 | 3: ant 98 | 4: Bill 99 | 5: Rob 100 | 6: 2luv3 101 | 7: 044 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /regtests/test/input/scan_cases: -------------------------------------------------------------------------------- 1 | # Test file used by testscanf.php. Feel free to add additional cases 2 | # sscanf test cases. formatted to be slurped and split by explode 3 | %d|48| valid decimal (positive) 4 | %d|-98| valid signed decimal (negative) 5 | %d|56a| integer scan : decimal digit followed by alpha 6 | %4d|558071|decimal integer with width specification 7 | %i|-5489|valid signed integer (negative) 8 | %s| the rain in spain | plain ole string matched with %s 9 | %10s|jabberwocky| string with width specifier 10 | %f|289.071| valid float (%f) 11 | %f|-0.403| valid negative (%f) 12 | %3f|76.4|Float with width specifier ending at decimal point 13 | %3f"|789.4|Float with width specifier 14 | %o|0321|octal with leading 0 15 | %o|327| valid octal digits 16 | %o|380| octal scan with octal digit followed by non-octal 17 | %x|fe| valid hex| 18 | %x|0xfe| "c" style hex with leading 0x| 19 | %x|455| hex with all single digits < f 20 | %x|-98| hex (negative signed int) 21 | %c|y| single char 22 | %4c|tulips|Character with width specification (4) 23 | %e|10e-9| signed floating point with negative exponent 24 | %e|10e+9| signed floating point with explicit positive exponent 25 | %e|10e9| signed floating point with positive exponent (no + sign) 26 | # next we test multiple cases 27 | %d %i %o %u %x %s %c %e %f %g | 19 84 0666 2000 0xface your x 31e+9 0.912 2.4 |multiple specifiers 28 | 29 | -------------------------------------------------------------------------------- /sample_tests/sample020.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample020.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Bug #42082 (NodeList length zero should be empty)
15 | --FILE--
16 | <?php
17 | $doc = new DOMDocument();
18 | $xpath = new DOMXPath($doc);
19 | $nodes = $xpath->query('*');
20 | var_dump($nodes);
21 | var_dump($nodes->length);
22 | $length = $nodes->length;
23 | var_dump(empty($nodes->length), empty($length));
24 | 
25 | $doc->loadXML("<element></element>");
26 | var_dump($doc->firstChild->nodeValue, empty($doc->firstChild->nodeValue), isset($doc->firstChild->nodeValue));
27 | var_dump(empty($doc->nodeType), empty($doc->firstChild->nodeType))
28 | ?>
29 | --EXPECTF--
30 | object(DOMNodeList)#%d (0) {
31 | }
32 | int(0)
33 | bool(true)
34 | bool(true)
35 | string(0) ""
36 | bool(true)
37 | bool(true)
38 | bool(false)
39 | bool(false)
40 |

Back to "PHPT Test File Layout"

41 |
42 | 43 | 46 | -------------------------------------------------------------------------------- /include/functions.php: -------------------------------------------------------------------------------- 1 | "/projects.php", "text" => "Goals"], 16 | ["href" => "/rc.php", "text" => "What is RC?"], 17 | ["href" => "/howtohelp.php", "text" => "Contributing"], 18 | ["href" => "/handling-bugs.php", "text" => "Handling Reports"], 19 | ["href" => "/reports/", "text" => "Reports"], 20 | ]; 21 | include __DIR__ . "/../shared/templates/header.inc"; 22 | echo '
'; 23 | } 24 | 25 | function common_footer($JS = []) { 26 | echo "
"; 27 | include __DIR__ . "/../shared/templates/footer.inc"; 28 | } 29 | 30 | function is_valid_php_version($version, $QA_RELEASES = []) { 31 | 32 | if (isset($QA_RELEASES['reported']) && in_array($version, $QA_RELEASES['reported'])) { 33 | return true; 34 | } 35 | 36 | if (preg_match('@^\d{1}\.\d{1}\.\d{1,}(?:(?:RC|alpha|beta)\d{0,2})?(?:-dev)?$@i', $version)) { 37 | return true; 38 | } 39 | 40 | return false; 41 | } 42 | -------------------------------------------------------------------------------- /sample_tests/clean.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: clean.inc

12 |

Back to "PHPT Test File Layout"

13 |
<?php
14 | include_once(__DIR__ . '/imap_include.inc');
15 | 
16 | $imap_stream = imap_open($default_mailbox, $username, $password);
17 | 
18 | // delete all msgs in default mailbox, i.e INBOX
19 | $check = imap_check($imap_stream);
20 | for ($i = 1; $i <= $check->Nmsgs; $i++) {
21 |   imap_delete($imap_stream, $i);
22 | }
23 | 
24 | $mailboxes = imap_getmailboxes($imap_stream, $server, '*');
25 | 
26 | foreach($mailboxes as $value) {
27 |   // Only delete mailboxes with our prefix
28 |   if (preg_match('/\{.*?\}INBOX\.(.+)/', $value->name, $match) == 1) {
29 |     if (strlen($match[1]) >= strlen($mailbox_prefix)
30 |     && substr_compare($match[1], $mailbox_prefix, 0, strlen($mailbox_prefix)) == 0) {
31 |       imap_deletemailbox($imap_stream, $value->name);
32 |     }
33 |   }
34 | }
35 | 
36 | imap_close($imap_stream, CL_EXPUNGE);
37 | ?>
38 |

Back to "PHPT Test File Layout"

39 |
40 | 41 | 44 | -------------------------------------------------------------------------------- /sample_tests/skipif.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: skipif.inc

12 |

Back to "PHPT Test File Layout"

13 |
<?php
14 | // This script prints "skip" if condition does not meet.
15 | if (!extension_loaded("session") && ini_get("enable_dl")) {
16 |   $dlext = (substr(PHP_OS, 0, 3) == "WIN") ? ".dll" : ".so";
17 |   @dl("session$dlext");
18 | }
19 | if (!extension_loaded("session")) {
20 |     die("skip Session module not loaded");
21 | }
22 | $save_path = ini_get("session.save_path");
23 | if ($save_path) {
24 |   if (!file_exists($save_path)) {
25 |     die("skip Session save_path doesn't exist");
26 |   }
27 | 
28 |   if ($save_path && !@is_writable($save_path)) {
29 |     if (($p = strpos($save_path, ';')) !== false) {
30 |       $save_path = substr($save_path, ++$p);
31 |     }
32 |     if (!@is_writable($save_path)) {
33 |       die("skip\n");
34 |     }
35 |   }
36 | }
37 | ?>
38 | 
39 |

Back to "PHPT Test File Layout"

40 |
41 | 42 | 45 | -------------------------------------------------------------------------------- /sample_tests/conflicts_1.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: conflicts_1.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Test get_headers() function : test with context
15 | --CONFLICTS--
16 | server
17 | --FILE--
18 | <?php
19 | 
20 | include __DIR__."/../../../../sapi/cli/tests/php_cli_server.inc";
21 | php_cli_server_start('header("X-Request-Method: ".$_SERVER["REQUEST_METHOD"]);');
22 | 
23 | $opts = array(
24 |     'http' => array(
25 |     'method' => 'HEAD'
26 |   )
27 | );
28 | 
29 | $context = stream_context_create($opts);
30 | $headers = get_headers("http://".PHP_CLI_SERVER_ADDRESS, 1, $context);
31 | echo $headers["X-Request-Method"]."\n";
32 | 
33 | stream_context_set_default($opts);
34 | $headers = get_headers("http://".PHP_CLI_SERVER_ADDRESS, 1);
35 | echo $headers["X-Request-Method"]."\n";
36 | 
37 | echo "Done";
38 | ?>
39 | --EXPECT--
40 | HEAD
41 | HEAD
42 | Done
43 | 
44 |

Back to "PHPT Test File Layout"

45 |
46 | 47 | 50 | -------------------------------------------------------------------------------- /sample_tests/sample024.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample024.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | DOMDocument::save  Test basic function of save method
15 | --SKIPIF--
16 | <?php
17 | require_once('skipif.inc');
18 | ?>
19 | --FILE--
20 | <?php
21 | $doc = new DOMDocument('1.0');
22 | $doc->formatOutput = true;
23 | 
24 | $root = $doc->createElement('book');
25 | 
26 | $root = $doc->appendChild($root);
27 | 
28 | $title = $doc->createElement('title');
29 | $title = $root->appendChild($title);
30 | 
31 | $text = $doc->createTextNode('This is the title');
32 | $text = $title->appendChild($text);
33 | 
34 | $temp_filename = __DIR__.'/DomDocument_save_basic.tmp';
35 | 
36 | echo 'Wrote: ' . $doc->save($temp_filename) . ' bytes'; // Wrote: 72 bytes
37 | ?>
38 | --CLEAN--
39 | <?php
40 |   unlink(__DIR__.'/DomDocument_save_basic.tmp');
41 | ?>
42 | --EXPECTF--
43 | Wrote: 72 bytes
44 | 
45 | 
46 |

Back to "PHPT Test File Layout"

47 |
48 | 49 | 52 | -------------------------------------------------------------------------------- /regtests/test/suite/bin/testdbaseaddrec.php: -------------------------------------------------------------------------------- 1 | 59 | -------------------------------------------------------------------------------- /reports/convert.php: -------------------------------------------------------------------------------- 1 | 'DROP TABLE IF exists expectedfail', 8 | 'expectedfail' => 'CREATE TABLE IF NOT EXISTS expectedfail ( 9 | `id` integer PRIMARY KEY AUTOINCREMENT, 10 | `id_report` bigint(20) NOT NULL, 11 | `test_name` varchar(128) NOT NULL 12 | )', 13 | 'success' => 'CREATE TABLE IF NOT EXISTS success ( 14 | `id` integer PRIMARY KEY AUTOINCREMENT, 15 | `id_report` bigint(20) NOT NULL, 16 | `test_name` varchar(128) NOT NULL 17 | )', 18 | ]; 19 | header('Content-Type: text/plain'); 20 | 21 | $d = dir('db'); 22 | while (false !== ($entry = $d->read())) { 23 | if (substr($entry, -6) == 'sqlite') { 24 | printf("%-20s ", $entry); 25 | $dbi = new SQLite3('db/'.$entry, SQLITE3_OPEN_READWRITE) or exit('cannot open DB to record results'); 26 | 27 | foreach ($queriesCreate as $table => $query) { 28 | $dbi->exec($query); 29 | if ($dbi->lastErrorCode() != '') echo $dbi->lastErrorMsg(); 30 | } 31 | // patch add field success 32 | @$dbi->exec('ALTER TABLE reports ADD COLUMN success unsigned int(10) NOT NULL default 0'); 33 | echo $dbi->lastErrorMsg(); 34 | 35 | $dbi->close(); 36 | echo "\n"; 37 | } 38 | } 39 | $d->close(); 40 | touch('db/update_20120407.lock'); 41 | -------------------------------------------------------------------------------- /sample_tests/sample008.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample008.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | GET/POST/REQUEST Test with input_filter
15 | --SKIPIF--
16 | <?php if (!extension_loaded("filter")) die("skip"); ?>
17 | --POST--
18 | d=379
19 | --GET--
20 | ar[elm1]=1234&ar[elm2]=0660&a=0234
21 | --FILE--
22 | <?php
23 | $ret = filter_input(INPUT_GET, 'a', FILTER_VALIDATE_INT);
24 | var_dump($ret);
25 | 
26 | $ret = filter_input(INPUT_GET, 'a', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL));
27 | var_dump($ret);
28 | 
29 | $ret = filter_input(INPUT_GET, 'ar', FILTER_VALIDATE_INT, array('flags'=>FILTER_REQUIRE_ARRAY));
30 | var_dump($ret);
31 | 
32 | $ret = filter_input(INPUT_GET, 'ar', FILTER_VALIDATE_INT, array('flags'=>FILTER_FLAG_ALLOW_OCTAL|FILTER_REQUIRE_ARRAY));
33 | var_dump($ret);
34 | 
35 | ?>
36 | --EXPECT--
37 | bool(false)
38 | int(156)
39 | array(2) {
40 |   ["elm1"]=>
41 |   int(1234)
42 |   ["elm2"]=>
43 |   bool(false)
44 | }
45 | array(2) {
46 |   ["elm1"]=>
47 |   int(1234)
48 |   ["elm2"]=>
49 |   int(432)
50 | }
51 | 
52 |

Back to "PHPT Test File Layout"

53 |
54 | 55 | 58 | -------------------------------------------------------------------------------- /howto_phpunit.php: -------------------------------------------------------------------------------- 1 | 11 | 12 |

13 | 14 |

Application - Application tested (Symfony, Joomla-Platform, Drupal, Mediawiki, Wordpress)

15 |

Scenario Set - Scenarios that are tested (CLI, Apache mod_php ; Opcache, Filesystem, etc...)

16 | 17 |

ERROR - PhpUnit tests that finished with Error(s)

18 |

FAILURE - PhpUnit tests that failed

19 |

TIMEOUT - Tests that did not finish after the maximum amount of time passed (usually one minute)

20 |

CRASH - Tests that Crashed PHP

21 | 22 |

Report compares ERROR, FAILURE, TIMEOUT, CRASH and PASS for two PHP Builds, the Base Build with the Test Build. A +X indicates the count increased from Base to Test. A -X indicates the count decreased from Base to Test. If the difference is good, it is shown in green (fe increase in PASS, decrease in ERROR). If the difference is bad, it is shown in red (fe increase in FAILURE).

23 | 24 |

Full Info on PFTT's PHPUnit Test Statuses

25 | 26 |

Result-Pack All the test logs are compressed into result-packs, which can be downloaded using the two links in the report.

27 | 28 | 31 | -------------------------------------------------------------------------------- /sample_tests/sample003.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample003.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | session object deserialization
15 | --SKIPIF--
16 | <?php include('skipif.inc'); ?>
17 | --INI--
18 | session.use_cookies=0
19 | session.cache_limiter=
20 | register_globals=1
21 | session.serialize_handler=php
22 | session.save_handler=files
23 | --FILE--
24 | <?php
25 | error_reporting(E_ALL);
26 | 
27 | class foo {
28 | 	public $bar = "ok";
29 | 	function method() { $this->yes++; }
30 | }
31 | 
32 | session_id("abtest");
33 | session_start();
34 | session_decode('baz|O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}arr|a:1:{i:3;O:3:"foo":2:{s:3:"bar";s:2:"ok";s:3:"yes";i:1;}}');
35 | 
36 | $baz->method();
37 | $arr[3]->method();
38 | 
39 | var_dump($baz);
40 | var_dump($arr);
41 | session_destroy();
42 | --EXPECT--
43 | object(foo)#1 (2) {
44 |   ["bar"]=>
45 |   string(2) "ok"
46 |   ["yes"]=>
47 |   int(2)
48 | }
49 | array(1) {
50 |   [3]=>
51 |   object(foo)#2 (2) {
52 |     ["bar"]=>
53 |     string(2) "ok"
54 |     ["yes"]=>
55 |     int(2)
56 |   }
57 | }
58 | 
59 |

Back to "PHPT Test File Layout"

60 |
61 | 62 | 65 | -------------------------------------------------------------------------------- /sample_tests/sample014.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample014.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | MySQL
15 | --SKIPIF--
16 | <?php # vim:ft=php
17 | if (!extension_loaded('pdo') || !extension_loaded('pdo_mysql')) print 'skip not loaded';
18 | ?>
19 | --REDIRECTTEST--
20 | # magic auto-configuration
21 | 
22 | $config = array(
23 |   'TESTS' => 'ext/pdo/tests'
24 | );
25 | 
26 | if (false !== getenv('PDO_MYSQL_TEST_DSN')) {
27 |   # user set them from their shell
28 |   $config['ENV']['PDOTEST_DSN'] = getenv('PDO_MYSQL_TEST_DSN');
29 |   $config['ENV']['PDOTEST_USER'] = getenv('PDO_MYSQL_TEST_USER');
30 |   $config['ENV']['PDOTEST_PASS'] = getenv('PDO_MYSQL_TEST_PASS');
31 |   if (false !== getenv('PDO_MYSQL_TEST_ATTR')) {
32 |     $config['ENV']['PDOTEST_ATTR'] = getenv('PDO_MYSQL_TEST_ATTR');
33 |   }
34 | } else {
35 |   $config['ENV']['PDOTEST_DSN'] = 'mysql:host=localhost;dbname=test';
36 |   $config['ENV']['PDOTEST_USER'] = 'root';
37 |   $config['ENV']['PDOTEST_PASS'] = '';
38 | }
39 | 
40 | return $config;
41 | 
42 |

Back to "PHPT Test File Layout"

43 |
44 | 45 | 48 | -------------------------------------------------------------------------------- /api.php: -------------------------------------------------------------------------------- 1 | 43 |

44 | The QA API is simple, and is based on the query string. 45 | Pass in type=qa-releases (the only type currently), along with the desired format (serialize or json). 46 |

47 | 48 |

49 | Example URLs: 50 |

54 |

55 | 9 | 10 |
11 |

Sample Test: sample001.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Phar::chmod
15 | --EXTENSIONS--
16 | phar
17 | --INI--
18 | phar.readonly=1
19 | phar.require_hash=0
20 | --SKIPIF--
21 | <?php
22 | if (getenv("GITHUB_ACTIONS") && PHP_OS_FAMILY === "Darwin") {
23 |     die("flaky Occasionally segfaults on macOS for unknown reasons");
24 | }
25 | ?>
26 | --FILE--
27 | <?php
28 | $fname = __DIR__ . '/' . basename(__FILE__, '.php') . '.1.phar.php';
29 | $pname = 'phar://hio';
30 | $file = '<?php include "' . $pname . '/a.php"; __HALT_COMPILER(); ?>';
31 | 
32 | $files = array();
33 | $files['a.php']   = '<?php echo "This is a\n"; include "'.$pname.'/b.php"; ?>';
34 | include 'files/phar_test.inc';
35 | try {
36 |     $a = new Phar($fname);
37 |     var_dump($a['a.php']->isExecutable());
38 |     $a['a.php']->chmod(0777);
39 |     var_dump($a['a.php']->isExecutable());
40 |     $a['a.php']->chmod(0666);
41 |     var_dump($a['a.php']->isExecutable());
42 | } catch (Exception $e) {
43 |     echo $e->getMessage() . "\n";
44 | }
45 | ?>
46 | --CLEAN--
47 | <?php
48 | unlink(__DIR__ . '/' . basename(__FILE__, '.clean.php') . '.1.phar.php');
49 | ?>
50 | --EXPECTF--
51 | bool(false)
52 | Cannot modify permissions for file "a.php" in phar "%s033a.1.phar.php", write operations are prohibited
53 | 
54 |

Back to "PHPT Test File Layout"

55 |
56 | 57 | 60 | -------------------------------------------------------------------------------- /list_builds.php: -------------------------------------------------------------------------------- 1 | ', htmlentities($branch), "\n"; 14 | echo "

Choose a PHP revision or build

\n"; 15 | 16 | (function() use ($branch) { 17 | $branchdir = makeBranchPath($branch); 18 | if (!is_dir($branchdir)) { return; } 19 | 20 | $revisions = scandir($branchdir); 21 | if ($revisions === false) { return; } 22 | 23 | $revisions = array_filter($revisions, function($rev) use ($branchdir) { 24 | return ($rev !== '.') && ($rev !== '..') && is_dir("$branchdir/$rev"); 25 | }); 26 | if (empty($revisions)) { return; } 27 | 28 | // Create an array of [ $rev => $mtime] pairs, 29 | // sorted by mtime from most recent to least. 30 | $revisions = array_flip($revisions); 31 | foreach ($revisions as $revision => &$mtime) { 32 | $mtime = filemtime("$branchdir/$revision"); 33 | } 34 | unset($mtime); 35 | arsort($revisions, SORT_NUMERIC); 36 | 37 | // Output revisions, from most recent to least. 38 | echo "\n"; 39 | foreach ($revisions as $revision => $mtime) { 40 | $revpath = makeRevisionPath($branch, $revision); 41 | if (!is_dir($revpath)) { continue; } 42 | $style = 'background: ' . 43 | (is_file("$revpath/FAIL_CRASH.txt") ? '#ff0000' : '#ccff66'); 44 | echo ""; 45 | echo '\n"; 48 | } 49 | echo "
', 47 | htmlentities($revision), "
\n"; 50 | echo "

\n"; 51 | })(); 52 | 53 | common_footer(); 54 | -------------------------------------------------------------------------------- /sample_tests/sample021.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample021.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Math constants
15 | --INI--
16 | precision=14
17 | --FILE--
18 | <?php
19 | $constants = array(
20 |     "M_E",
21 |     "M_LOG2E",
22 |     "M_LOG10E",
23 |     "M_LN2",
24 |     "M_LN10",
25 |     "M_PI",
26 |     "M_PI_2",
27 |     "M_PI_4",
28 |     "M_1_PI",
29 |     "M_2_PI",
30 |     "M_SQRTPI",
31 |     "M_2_SQRTPI",
32 |     "M_LNPI",
33 |     "M_EULER",
34 |     "M_SQRT2",
35 |     "M_SQRT1_2",
36 |     "M_SQRT3"
37 | );
38 | foreach($constants as $constant) {
39 |     printf("%-10s: %s\n", $constant, constant($constant));
40 | }
41 | ?>
42 | --EXPECTREGEX--
43 | M_E       : 2.718281[0-9]*
44 | M_LOG2E   : 1.442695[0-9]*
45 | M_LOG10E  : 0.434294[0-9]*
46 | M_LN2     : 0.693147[0-9]*
47 | M_LN10    : 2.302585[0-9]*
48 | M_PI      : 3.141592[0-9]*
49 | M_PI_2    : 1.570796[0-9]*
50 | M_PI_4    : 0.785398[0-9]*
51 | M_1_PI    : 0.318309[0-9]*
52 | M_2_PI    : 0.636619[0-9]*
53 | M_SQRTPI  : 1.772453[0-9]*
54 | M_2_SQRTPI: 1.128379[0-9]*
55 | M_LNPI    : 1.144729[0-9]*
56 | M_EULER   : 0.577215[0-9]*
57 | M_SQRT2   : 1.414213[0-9]*
58 | M_SQRT1_2 : 0.707106[0-9]*
59 | M_SQRT3   : 1.732050[0-9]*
60 | 
61 | 
62 |

Back to "PHPT Test File Layout"

63 |
64 | 65 | 68 | -------------------------------------------------------------------------------- /sample_tests/sample006.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample006.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | is_uploaded_file() function
15 | --CREDITS--
16 | Dave Kelsey <d_kelsey@uk.ibm.com>
17 | --SKIPIF--
18 | <?php if (php_sapi_name()=='cli') die('skip'); ?>
19 | --POST_RAW--
20 | Content-type: multipart/form-data, boundary=AaB03x
21 | 
22 | --AaB03x
23 | content-disposition: form-data; name="field1"
24 | 
25 | Joe Blow
26 | --AaB03x
27 | content-disposition: form-data; name="pics"; filename="file1.txt"
28 | Content-Type: text/plain
29 | 
30 | abcdef123456789
31 | --AaB03x--
32 | --FILE--
33 | <?php
34 | // uploaded file
35 | var_dump(is_uploaded_file($_FILES['pics']['tmp_name']));
36 | 
37 | // not an uploaded file
38 | var_dump(is_uploaded_file($_FILES['pics']['name']));
39 | 
40 | // not an uploaded file
41 | var_dump(is_uploaded_file('random_filename.txt'));
42 | 
43 | // not an uploaded file
44 | var_dump(is_uploaded_file('__FILE__'));
45 | 
46 | // Error cases
47 | var_dump(is_uploaded_file());
48 | var_dump(is_uploaded_file('a', 'b'));
49 | 
50 | ?>
51 | --EXPECTF--
52 | bool(true)
53 | bool(false)
54 | bool(false)
55 | bool(false)
56 | 
57 | Warning: is_uploaded_file() expects exactly 1 parameter, 0 given in %s on line %d
58 | NULL
59 | 
60 | Warning: is_uploaded_file() expects exactly 1 parameter, 2 given in %s on line %d
61 | NULL
62 | 
63 | 
64 |

Back to "PHPT Test File Layout"

65 |
66 | 67 | 70 | -------------------------------------------------------------------------------- /regtests/README: -------------------------------------------------------------------------------- 1 | ________Test Suite for PHP__________ 2 | 3 | This test suite is based around a test setup written by Fred Wild 4 | and published in Dr Dobbs Journal in June 1998 5 | 6 | Modified by jalal @ gnomedia for running php tests. 7 | 8 | __Overview__ 9 | 10 | The purpose of the test suite is to allow testers to design 11 | a test script and then drop it into the test suite and have 12 | it run automatically. To this end, each test requires at a 13 | minimum two files: the script and the ideal output. In order 14 | for the suite to function automatically, there is a fixed structure 15 | for the suite and the test files. 16 | 17 | 18 | __Directory structure__ 19 | 20 | regtests/ --the maketests script 21 | |--test --the master and compare scripts 22 | |--actuals --the created output 23 | |--ideals --the ideal, expected output 24 | |--input --optional input files 25 | |--suite 26 | |--bin --the scripts 27 | |--common --not used 28 | |--post --not used 29 | |--pre --not used 30 | 31 | 32 | 33 | __File Naming Convention__ 34 | 35 | All scripts must end in .php 36 | All pre and post scripts should end in .php 37 | All ideal output files must end in .out 38 | If a test script is based on a bug, use the number of the bug for the script name. 39 | 40 | 41 | __How it works__ 42 | 43 | First create a test script, we'll call it mybugtest.php 44 | This script should output the results of running the script 45 | in whatever format is suitable. 46 | Run the script: 47 | #:>php -f mybugtest.php > mybugtest.out 48 | 49 | Copy the script into test/suite/bin 50 | Copy the output into test/ideal 51 | 52 | Run maketests 53 | This will reproduce the master and the compare scripts 54 | 55 | #:>. ./test/master 56 | this will run all the tests and produce files in the test/actual 57 | directory 58 | 59 | 60 | #:>. ./test/compare 61 | this will run diff over the outputs and put the results in 62 | test/compare.out 63 | -------------------------------------------------------------------------------- /regtests/test/actuals/testarray2.out: -------------------------------------------------------------------------------- 1 | 2 | aaaaabaacaadaaeaafaagaahaaiaajaakaalaamaanaaoaapaaqaaraasaataauaavaawaaxaayaazabaabbabcabdabeabfabgabhabiabjabkablabmabnaboabpabqabrabsabtabuabvabwabxabyabzacaacbaccacdaceacfacgachaciacjackaclacmacnacoacpacqacracsactacuacvacwacxacyaczadaadbadcaddadeadfadgadhadiadjadkadladmadnadoadpadqadradsadtaduadvadwadxadyadzaeaaebaecaedaeeaefaegaehaeiaejaekaelaemaenaeoaepaeqaeraesaetaeuaevaewaexaeyaezafaafbafcafdafeaffafgafhafiafjafkaflafmafnafoafpafqafrafsaftafuafvafwafxafyafzagaagbagcagdageagfaggaghagiagjagkaglagmagnagoagpagqagragsagtaguagvagwagxagyagzahaahbahcahdaheahfahgahhahiahjahkahlahmahnahoahpahqahrahsahtahuahvahwahxahyahzaiaaibaicaidaieaifaigaihaiiaijaikailaimainaioaipaiqairaisaitaiuaivaiwaixaiyaizajaajbajcajdajeajfajgajhajiajjajkajlajmajnajoajpajqajrajsajtajuajvajwajxajyajzakaakbakcakdakeakfakgakhakiakjakkaklakmaknakoakpakqakraksaktakuakvakwakxakyakzalaalbalcaldalealfalgalhalialjalkallalmalnaloalpalqalralsaltalualvalwalxalyalzamaambamcamdameamfamgamhamiamjamkamlammamnamoampamqamramsamtamuamvamwamxamyamzanaanbancandaneanfanganhanianjankanlanmannanoanpanqanransantanuanvanwanxanyanzaoaaobaocaodaoeaofaogaohaoiaojaokaolaomaonaooaopaoqaoraosaotaouaovaowaoxaoyaozapaapbapcapdapeapfapgaphapiapjapkaplapmapnapoappapqaprapsaptapuapvapwapxapyapzaqaaqbaqcaqdaqeaqfaqgaqhaqiaqjaqkaqlaqmaqnaqoaqpaqqaqraqsaqtaquaqvaqwaqxaqyaqzaraarbarcardarearfargarhariarjarkarlarmarnaroarparqarrarsartaruarvarwarxaryarzasaasbascasdaseasfasgashasiasjaskaslasmasnasoaspasqasrassastasuasvaswasxasyaszataatbatcatdateatfatgathatiatjatkatlatmatnatoatpatqatratsattatuatvatwatxatyatzauaaubaucaudaueaufaugauhauiaujaukaulaumaunauoaupauqaurausautauuauvauwauxauyauzavaavbavcavdaveavfavgavhaviavjavkavlavmavnavoavpavqavravsavtavuavvavwavxavyavzawaawbawcawdaweawfawgawhawiawjawkawlawmawnawoawpawqawrawsawtawuawvawwawxawyawzaxaaxbaxcaxdaxeaxfaxgaxhaxiaxjaxkaxlaxmaxnaxoaxpaxqaxraxsaxtaxuaxvaxwaxxaxyaxzayaaybaycaydayeayfaygayhayiayjaykaylaymaynayoaypayqayraysaytayuayvaywayxayyayzazaazbazcazdazeazfazgazhaziazjazkazlazmaznazoazpazqazrazsaztazuazvazwazxazyazzbaababbacbadbaebafbagbahbaibajbakbalbambanbaobapbaqbarbasbatbaubavbawbaxbaybazbbabbb -------------------------------------------------------------------------------- /regtests/test/ideals/testarray2.out: -------------------------------------------------------------------------------- 1 | 2 | aaaaabaacaadaaeaafaagaahaaiaajaakaalaamaanaaoaapaaqaaraasaataauaavaawaaxaayaazabaabbabcabdabeabfabgabhabiabjabkablabmabnaboabpabqabrabsabtabuabvabwabxabyabzacaacbaccacdaceacfacgachaciacjackaclacmacnacoacpacqacracsactacuacvacwacxacyaczadaadbadcaddadeadfadgadhadiadjadkadladmadnadoadpadqadradsadtaduadvadwadxadyadzaeaaebaecaedaeeaefaegaehaeiaejaekaelaemaenaeoaepaeqaeraesaetaeuaevaewaexaeyaezafaafbafcafdafeaffafgafhafiafjafkaflafmafnafoafpafqafrafsaftafuafvafwafxafyafzagaagbagcagdageagfaggaghagiagjagkaglagmagnagoagpagqagragsagtaguagvagwagxagyagzahaahbahcahdaheahfahgahhahiahjahkahlahmahnahoahpahqahrahsahtahuahvahwahxahyahzaiaaibaicaidaieaifaigaihaiiaijaikailaimainaioaipaiqairaisaitaiuaivaiwaixaiyaizajaajbajcajdajeajfajgajhajiajjajkajlajmajnajoajpajqajrajsajtajuajvajwajxajyajzakaakbakcakdakeakfakgakhakiakjakkaklakmaknakoakpakqakraksaktakuakvakwakxakyakzalaalbalcaldalealfalgalhalialjalkallalmalnaloalpalqalralsaltalualvalwalxalyalzamaambamcamdameamfamgamhamiamjamkamlammamnamoampamqamramsamtamuamvamwamxamyamzanaanbancandaneanfanganhanianjankanlanmannanoanpanqanransantanuanvanwanxanyanzaoaaobaocaodaoeaofaogaohaoiaojaokaolaomaonaooaopaoqaoraosaotaouaovaowaoxaoyaozapaapbapcapdapeapfapgaphapiapjapkaplapmapnapoappapqaprapsaptapuapvapwapxapyapzaqaaqbaqcaqdaqeaqfaqgaqhaqiaqjaqkaqlaqmaqnaqoaqpaqqaqraqsaqtaquaqvaqwaqxaqyaqzaraarbarcardarearfargarhariarjarkarlarmarnaroarparqarrarsartaruarvarwarxaryarzasaasbascasdaseasfasgashasiasjaskaslasmasnasoaspasqasrassastasuasvaswasxasyaszataatbatcatdateatfatgathatiatjatkatlatmatnatoatpatqatratsattatuatvatwatxatyatzauaaubaucaudaueaufaugauhauiaujaukaulaumaunauoaupauqaurausautauuauvauwauxauyauzavaavbavcavdaveavfavgavhaviavjavkavlavmavnavoavpavqavravsavtavuavvavwavxavyavzawaawbawcawdaweawfawgawhawiawjawkawlawmawnawoawpawqawrawsawtawuawvawwawxawyawzaxaaxbaxcaxdaxeaxfaxgaxhaxiaxjaxkaxlaxmaxnaxoaxpaxqaxraxsaxtaxuaxvaxwaxxaxyaxzayaaybaycaydayeayfaygayhayiayjaykaylaymaynayoaypayqayraysaytayuayvaywayxayyayzazaazbazcazdazeazfazgazhaziazjazkazlazmaznazoazpazqazrazsaztazuazvazwazxazyazzbaababbacbadbaebafbagbahbaibajbakbalbambanbaobapbaqbarbasbatbaubavbawbaxbaybazbbabbb -------------------------------------------------------------------------------- /sample_tests/sample022.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample022.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | shm_detach() tests
15 | --SKIPIF--
16 | <?php if (!extension_loaded("sysvshm")) print "skip"; ?>
17 | --FILE--
18 | <?php
19 | 
20 | $key = ftok(__DIR__.'/003.phpt', 'q');
21 | 
22 | var_dump(shm_detach());
23 | var_dump(shm_detach(1,1));
24 | 
25 | $s = shm_attach($key);
26 | 
27 | var_dump(shm_detach($s));
28 | var_dump(shm_detach($s));
29 | shm_remove($s);
30 | 
31 | var_dump(shm_detach(0));
32 | var_dump(shm_detach(1));
33 | var_dump(shm_detach(-1));
34 | 
35 | echo "Done\n";
36 | ?>
37 | --CLEAN--
38 | <?php
39 | $key = ftok(__DIR__."/003.phpt", 'q');
40 | $s = shm_attach($key);
41 | shm_remove($s);
42 | ?>
43 | --EXPECTF--
44 | Warning: shm_detach() expects exactly 1 parameter, 0 given in %ssample022.php on line %d
45 | NULL
46 | 
47 | Warning: shm_detach() expects exactly 1 parameter, 2 given in %ssample022.php on line %d
48 | NULL
49 | bool(true)
50 | 
51 | Warning: shm_detach(): %d is not a valid sysvshm resource in %ssample022.php on line %d
52 | bool(false)
53 | 
54 | Warning: shm_remove(): %d is not a valid sysvshm resource in %ssample022.php on line %d
55 | 
56 | Warning: shm_detach() expects parameter 1 to be resource, integer given in %ssample022.php on line %d
57 | NULL
58 | 
59 | Warning: shm_detach() expects parameter 1 to be resource, integer given in %ssample022.php on line %d
60 | NULL
61 | 
62 | Warning: shm_detach() expects parameter 1 to be resource, integer given in %ssample022.php on line %d
63 | NULL
64 | Done
65 | 
66 |

Back to "PHPT Test File Layout"

67 |
68 | 69 | 72 | -------------------------------------------------------------------------------- /howto_phpt.php: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 |

PFTT Command - Run this command in the PFTT Shell to reproduce the same tests. Use the `rg` command to get the same release if you don't already have it. Download and install PFTT from https://qa.php.net/pftt.php.

15 | 16 |

Scenario Set - Scenarios that are tested (CLI, Apache mod_php ; Opcache, Filesystem, etc...)

17 | 18 |

FAILED - PHPT tests that failed

19 |

TIMEOUT - PHPT tests that did not finish after a minute

20 |

CRASH - PHPT tests that CRASHed PHP

21 |

SKIP - PHPT test that was not run. Should minimize this count as much as possible for better code coverage

22 |

XSKIP - PHPT test that could not be run on OS. It is ok to skip these tests (whereas SKIP tests should be run if possible)

23 | 24 |

Report compares ERROR, FAILURE, TIMEOUT, CRASH and PASS for two PHP Builds, the Base Build with the Test Build. A +X indicates the count increased from Base to Test. A -X indicates the count decreased from Base to Test. If the difference is good, it is shown in green (fe increase in PASS, decrease in FAIL). If the difference is bad, it is shown in red (fe increase in FAIL).

25 | 26 |

Full info on PHPT Test Statuses

27 | 28 |

Result-Pack All the test logs are compressed into result-packs, which can be downloaded using the two links in the report.

29 | 30 | 33 | -------------------------------------------------------------------------------- /sample_tests/sample019.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample019.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | bzopen() and invalid parameters
15 | --SKIPIF--
16 | <?php if (!extension_loaded("bz2")) print "skip"; ?>
17 | --FILE--
18 | <?php
19 | 
20 | var_dump(bzopen());
21 | var_dump(bzopen("", ""));
22 | var_dump(bzopen("", "r"));
23 | var_dump(bzopen("", "w"));
24 | var_dump(bzopen("", "x"));
25 | var_dump(bzopen("", "rw"));
26 | var_dump(bzopen("no_such_file", "r"));
27 | 
28 | $fp = fopen(__FILE__,"r");
29 | var_dump(bzopen($fp, "r"));
30 | 
31 | echo "Done\n";
32 | ?>
33 | --EXPECTF--
34 | Warning: bzopen() expects exactly 2 parameters, 0 given in %s on line %d
35 | NULL
36 | 
37 | Warning: bzopen(): '' is not a valid mode for bzopen(). Only 'w' and 'r' are supported. in %s on line %d
38 | bool(false)
39 | 
40 | Warning: bzopen(): filename cannot be empty in %s on line %d
41 | bool(false)
42 | 
43 | Warning: bzopen(): filename cannot be empty in %s on line %d
44 | bool(false)
45 | 
46 | Warning: bzopen(): 'x' is not a valid mode for bzopen(). Only 'w' and 'r' are supported. in %s on line %d
47 | bool(false)
48 | 
49 | Warning: bzopen(): 'rw' is not a valid mode for bzopen(). Only 'w' and 'r' are supported. in %s on line %d
50 | bool(false)
51 | 
52 | Warning: bzopen(no_such_file): failed to open stream: No such file or directory in %s on line %d
53 | bool(false)
54 | resource(%d) of type (stream)
55 | Done
56 | 
57 |

Back to "PHPT Test File Layout"

58 |
59 | 60 | 63 | -------------------------------------------------------------------------------- /pftt.php: -------------------------------------------------------------------------------- 1 | 13 |

PFTT

14 | 15 |

Choose a PHP Branch

16 | 17 | $latest_revision_mtime) { 35 | $latest_revision = $revision; 36 | $latest_revision_mtime = $mtime; 37 | } 38 | } 39 | } 40 | 41 | $red = is_file(BASE_REPORT_DIR."/$branch/$latest_revision/FAIL_CRASH.txt"); 42 | 43 | ?> 44 | 45 | 46 | 47 | 48 | 49 | 50 |
Latest:
51 |
52 | 59 | 60 |

PFTT Source Code: https://github.com/php/pftt2

61 | 62 |

PFTT Binaries: https://windows.php.net/downloads/snaps/ostc/pftt/

63 | 64 |
65 |
66 | 70 | -------------------------------------------------------------------------------- /regtests/test/suite/bin/arraysort.php: -------------------------------------------------------------------------------- 1 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /sample_tests/sample005.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample005.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | SOAP Server 19: compressed request (gzip)
15 | --SKIPIF--
16 | <?php
17 |   if (php_sapi_name()=='cli') echo 'skip';
18 |   require_once('skipif2.inc');
19 |   if (!extension_loaded('zlib')) die('skip zlib extension not available');
20 | ?>
21 | --INI--
22 | precision=14
23 | --GZIP_POST--
24 | <SOAP-ENV:Envelope
25 |   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
26 |   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
27 |   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
28 |   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
29 |   xmlns:si="http://soapinterop.org/xsd">
30 |   <SOAP-ENV:Body>
31 |     <ns1:test xmlns:ns1="http://testuri.org" />
32 |   </SOAP-ENV:Body>
33 | </SOAP-ENV:Envelope>
34 | --FILE--
35 | <?php
36 | function test() {
37 |   return "Hello World";
38 | }
39 | 
40 | $server = new soapserver(null,array('uri'=>"http://testuri.org"));
41 | $server->addfunction("test");
42 | $server->handle();
43 | echo "ok\n";
44 | ?>
45 | --EXPECT--
46 | <?xml version="1.0" encoding="UTF-8"?>
47 | <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:testResponse><return xsi:type="xsd:string">Hello World</return></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
48 | ok
49 | 
50 |

Back to "PHPT Test File Layout"

51 |
52 | 53 | 56 | -------------------------------------------------------------------------------- /rc.php: -------------------------------------------------------------------------------- 1 | 11 |

Release Candidates

12 |

Basics

13 |

14 | Release candidates are development packages released to check if any critical 15 | problems have slipped into the code during the previous development period. 16 | Release candidates are NOT for production use, they are for testing purposes only 17 | even though in most cases there are almost no differences between the general 18 | availability (GA) release and the last RC. 19 | You can help the PHP Team and yourself detect problems by installing and testing 20 | release candidates on your own (non-production!) server. 21 |

22 |

Installation problems

23 |

24 | First of all, make sure the build process (on *nix only) and installation went fine for you. 25 | PHP supports quite a number of operating systems on different platforms and we continue 26 | to work on increasing this number. 27 | If you encounter any problems during the installation, we would like to know about them. 28 |

29 |

Testing the installation

30 |

31 | When done with the build, please run the test engine by using the 'make test' command 32 | and send us the results (hit 'Y' when it asks you whether to send the report). 33 | This way we'll receive the required information about your system to fix the problems 34 | detected by the test suite (if any). Each and every report goes towards helping us 35 | provide the best software we can, your feedback is a valuable resource and the 36 | PHP group would hereby like to extend their gratitude for your effort. 37 |

38 |

Real-life tests

39 |

40 | We would also appreciate if you install the RC on your development server and run 41 | your software. This would help us to detect any unintentional changes between 42 | the release candidates and general releases. 43 | Such real-life tests are the most valuable because our test suite does not yet 44 | cover every possible use case (but we're working on that). 45 |

46 |

Getting the Release Candidates

47 |

48 | The release candidates are available for download from the QA frontpage. 49 |

50 | 54 | -------------------------------------------------------------------------------- /sample_tests/sample007.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample007.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | SOAP Server 20: compressed request (deflate)
15 | --SKIPIF--
16 | <?php
17 |   if (php_sapi_name()=='cli') echo 'skip';
18 |   require_once('skipif2.inc');
19 |   if (!extension_loaded('zlib')) die('skip zlib extension not available');
20 | ?>
21 | --INI--
22 | precision=14
23 | --DEFLATE_POST--
24 | <?xml version="1.0" encoding="ISO-8859-1"?>
25 | <SOAP-ENV:Envelope
26 |   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
27 |   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
28 |   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
29 |   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
30 |   xmlns:si="http://soapinterop.org/xsd">
31 |   <SOAP-ENV:Body>
32 |     <ns1:test xmlns:ns1="http://testuri.org" />
33 |   </SOAP-ENV:Body>
34 | </SOAP-ENV:Envelope>
35 | --FILE--
36 | <?php
37 | function test() {
38 |   return "Hello World";
39 | }
40 | 
41 | $server = new soapserver(null,array('uri'=>"http://testuri.org"));
42 | $server->addfunction("test");
43 | $server->handle();
44 | echo "ok\n";
45 | ?>
46 | --EXPECT--
47 | <?xml version="1.0" encoding="UTF-8"?>
48 | <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:testResponse><return xsi:type="xsd:string">Hello World</return></ns1:testResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
49 | ok
50 | 
51 |

Back to "PHPT Test File Layout"

52 |
53 | 54 | 57 | -------------------------------------------------------------------------------- /howtohelp.php: -------------------------------------------------------------------------------- 1 | 11 |

How You Can Help

12 |

So there you sit. A PHP coder who loves PHP. But lately 13 | you find yourself wanting to help the PHP community by contributing. Only 14 | one problem - you aren't a uber 1337 coder - whether it is because you have 15 | only recently started to learn how to program in PHP or you just don't yet 16 | have the experience with advanced concepts. But you really want to help out 17 | and you are unsure though how to go about doing it. You have looked at the 18 | various 'normal' ways of helping out with PHP but nothing seems to fit. Your 19 | C coding isn't the best (if you even know how) so helping with the core or 20 | PECL is out, nothing in PEAR really 'calls' to you, and you don't know anything 21 | about the PHP docs and the software it uses. So where does that leave you. 22 | Have no fear there is still a way you can help with PHP - you can help the 23 | PHP Quality Assurance team.
24 |

25 | 47 | 51 | -------------------------------------------------------------------------------- /sample_tests/sample017.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample017.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | PDO Common: Bug #34630 (inserting streams as LOBs)
15 | --SKIPIF--
16 | <?php # vim:ft=php
17 | if (!extension_loaded('pdo')) die('skip');
18 | $dir = getenv('REDIR_TEST_DIR');
19 | if (false == $dir) die('skip no driver');
20 | require_once $dir . 'pdo_test.inc';
21 | PDOTest::skip();
22 | ?>
23 | --FILE--
24 | <?php
25 | if (getenv('REDIR_TEST_DIR') === false) putenv('REDIR_TEST_DIR='.__DIR__ . '/../../pdo/tests/');
26 | require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
27 | $db = PDOTest::factory();
28 | 
29 | $driver = $db->getAttribute(PDO::ATTR_DRIVER_NAME);
30 | $is_oci = $driver == 'oci';
31 | 
32 | if ($is_oci) {
33 |   $db->exec('CREATE TABLE test (id int NOT NULL PRIMARY KEY, val BLOB)');
34 | } else {
35 |   $db->exec('CREATE TABLE test (id int NOT NULL PRIMARY KEY, val VARCHAR(256))');
36 | }
37 | $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
38 | 
39 | $fp = tmpfile();
40 | fwrite($fp, "I am the LOB data");
41 | rewind($fp);
42 | 
43 | if ($is_oci) {
44 |   /* oracle is a bit different; you need to initiate a transaction otherwise
45 |    * the empty blob will be committed implicitly when the statement is
46 |    * executed */
47 |   $db->beginTransaction();
48 |   $insert = $db->prepare("insert into test (id, val) values (1, EMPTY_BLOB()) RETURNING val INTO :blob");
49 | } else {
50 |   $insert = $db->prepare("insert into test (id, val) values (1, :blob)");
51 | }
52 | $insert->bindValue(':blob', $fp, PDO::PARAM_LOB);
53 | $insert->execute();
54 | $insert = null;
55 | 
56 | $db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true);
57 | var_dump($db->query("SELECT * from test")->fetchAll(PDO::FETCH_ASSOC));
58 | 
59 | ?>
60 | --XFAIL--
61 | This bug might be still open on aix5.2-ppc64 and hpux11.23-ia64
62 | --EXPECT--
63 | array(1) {
64 |   [0]=>
65 |   array(2) {
66 |     ["id"]=>
67 |     string(1) "1"
68 |     ["val"]=>
69 |     string(17) "I am the LOB data"
70 |   }
71 | }
72 | 
73 |

Back to "PHPT Test File Layout"

74 |
75 | 76 | 79 | -------------------------------------------------------------------------------- /regtests/test/ideals/testdbaseaddrec.out: -------------------------------------------------------------------------------- 1 | Before anything that should crash us... 2 | array(4) { 3 | [1]=> 4 | array(5) { 5 | ["code"]=> 6 | string(12) "test " 7 | ["name_g"]=> 8 | string(200) "test2 " 9 | ["name_r"]=> 10 | string(200) "test3 " 11 | ["ao_dm"]=> 12 | float(2) 13 | ["deleted"]=> 14 | int(0) 15 | 16 | } 17 | [2]=> 18 | array(5) { 19 | ["code"]=> 20 | string(12) "test " 21 | ["name_g"]=> 22 | string(200) "test2 " 23 | ["name_r"]=> 24 | string(200) "test3 " 25 | ["ao_dm"]=> 26 | float(2) 27 | ["deleted"]=> 28 | int(0) 29 | 30 | } 31 | [3]=> 32 | array(5) { 33 | ["code"]=> 34 | string(12) "test " 35 | ["name_g"]=> 36 | string(200) "test2 " 37 | ["name_r"]=> 38 | string(200) "test3 " 39 | ["ao_dm"]=> 40 | float(2) 41 | ["deleted"]=> 42 | int(0) 43 | 44 | } 45 | [4]=> 46 | array(5) { 47 | ["code"]=> 48 | string(12) "test " 49 | ["name_g"]=> 50 | string(200) "test2 " 51 | ["name_r"]=> 52 | string(200) "test3 " 53 | ["ao_dm"]=> 54 | float(2) 55 | ["deleted"]=> 56 | int(0) 57 | 58 | } 59 | } 60 | After anything that should crash us... 61 | -------------------------------------------------------------------------------- /expectf_details.php: -------------------------------------------------------------------------------- 1 | 9 |

EXPECTF substitution options

10 |

The --EXPECTF-- section uses a number of substitution tags for strings or digits 11 | that appear in test case output but which may vary between test runs. The most common 12 | example of this is to use %s and %d to match the file path and line number which are 13 | output by PHP Warnings.

14 | 15 |

The substitution tags and their meanings are summarised below

16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 |
%code Meaning
%e Represents a directory separator, for example / on Linux.
%s One or more of anything (character or white space) except the end of line character.
%S Zero or more of anything (character or white space) except the end of line character.
%a One or more of anything (character or white space) including the end of line character.
%A Zero or more of anything (character or white space) including the end of line character.
%w Zero or more white space characters.
%i A signed integer value, for example +3142, -3142.
%d An unsigned integer value, for example 123456.
%x One or more hexadecimal character. That is, characters in the range 0-9, a-f, A-F.
%f A floating point number, for example: 3.142, -3.142, 3.142E-10, 3.142e+10.
%c A single character of any sort (.)
%r...%r Any string (...) enclosed between two %r will be treated as a regular expression
%unicode|string% Matches the string 'unicode' in PHP6 test output and 'string' in PHP5 test output.
%binary_string_optional% Matches 'Binary string' in PHP6 output, 'string' in PHP5 output. Used in PHP Warning messages.
%unicode_string_optional% Matches 'Unicode string' in PHP6 output, 'string' in PHP5 output. Used in PHP Warning messages.
%u|b% Matches a single 'u' in PHP6 test output where the PHP5 output from the same test has no character in that position.
87 | 88 | 89 | 9 | 10 |
11 |

Sample Test: sample001.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Test filter_input() with GET and POST data.
15 | --DESCRIPTION--
16 | This test covers both valid and invalid usages of
17 | filter_input() with INPUT_GET and INPUT_POST data
18 | and several differnt filter sanitizers.
19 | --CREDITS--
20 | Felipe Pena <felipe@php.net>
21 | --INI--
22 | precision=14
23 | --SKIPIF--
24 | <?php if (!extension_loaded("filter")) die("Skipped: filter extension required."); ?>
25 | --GET--
26 | a=<b>test</b>&b=https://example.com
27 | --POST--
28 | c=<p>string</p>&d=12345.7
29 | --FILE--
30 | <?php
31 | ini_set('html_errors', false);
32 | var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_STRIPPED));
33 | var_dump(filter_input(INPUT_GET, "b", FILTER_SANITIZE_URL));
34 | var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_SPECIAL_CHARS, array(1,2,3,4,5)));
35 | var_dump(filter_input(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass));
36 | var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_STRIPPED, array(5,6,7,8)));
37 | var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_FLOAT));
38 | var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_SPECIAL_CHARS));
39 | var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_INT));
40 | var_dump(filter_var(new stdClass, "d"));
41 | var_dump(filter_input(INPUT_POST, "c", "", ""));
42 | var_dump(filter_var("", "", "", "", ""));
43 | var_dump(filter_var(0, 0, 0, 0, 0));
44 | echo "Done\n";
45 | ?>
46 | --EXPECTF--
47 | string(4) "test"
48 | string(19) "https://example.com"
49 | string(27) "&#60;b&#62;test&#60;/b&#62;"
50 | 
51 | Notice: Object of class stdClass could not be converted to int in %ssample001.php on line %d
52 | bool(false)
53 | string(6) "string"
54 | float(12345.7)
55 | string(29) "&#60;p&#62;string&#60;/p&#62;"
56 | bool(false)
57 | 
58 | Warning: filter_var() expects parameter 2 to be long, string given in %ssample001.php on line %d
59 | NULL
60 | 
61 | Warning: filter_input() expects parameter 3 to be long, string given in %ssample001.php on line %d
62 | NULL
63 | 
64 | Warning: filter_var() expects at most 3 parameters, 5 given in %ssample001.php on line %d
65 | NULL
66 | 
67 | Warning: filter_var() expects at most 3 parameters, 5 given in %ssample001.php on line %d
68 | NULL
69 | Done
70 | 
71 |

Back to "PHPT Test File Layout"

72 |
73 | 74 | 77 | -------------------------------------------------------------------------------- /reports/README: -------------------------------------------------------------------------------- 1 | Database format 2 | --------------- 3 | In db/ folder, there is one file for each PHP version. 4 | The sqlite files CANNOT be access directly (forced to use the report interface). 5 | 6 | Each sqlite file has the following schema : 7 | 8 | CREATE TABLE failed ( 9 | `id` integer PRIMARY KEY AUTOINCREMENT, 10 | `id_report` bigint(20) NOT NULL, 11 | `test_name` varchar(128) NOT NULL, 12 | `output` STRING NOT NULL, 13 | `diff` STRING NOT NULL, 14 | `signature` binary(16) NOT NULL 15 | ) 16 | CREATE TABLE reports ( 17 | id integer primary key AUTOINCREMENT, 18 | date datetime NOT NULL, 19 | status smallint(1) not null, 20 | nb_failed unsigned int(10) NOT NULL, 21 | nb_expected_fail unsigned int(10) NOT NULL, 22 | build_env STRING NOT NULL, 23 | phpinfo STRING NOT NULL, 24 | user_email varchar(64) default null 25 | ) 26 | 27 | The SQLite file is created in parserfunc.php:insertToDb_phpmaketest() 28 | if the sqlite file '$VERSION.sqlite' does not exist. 29 | 30 | Each report adds a line in `reports` table with the following fields : 31 | - id : integer auto incremented 32 | - date : date the report was sent 33 | - status : 0 = failed, 1 = success. If status is something else (should not !), we exit() 34 | - nb_failed : number of tests failed 35 | - nb_expected_fail : number of expected failed tests 36 | - build_env : build environment 37 | - phpinfo : phpinfo() output 38 | - user_email : email mangled (user at domain dot com) 39 | 40 | Then, for each failed test, we add a line in `failed` table : 41 | - id : integer auto increment 42 | - id_report : id of the report 43 | - test_name : path of the test. Example : "/ext/hash/tests/mhash_001.phpt" 44 | - output : full output of test 45 | - diff : diff of test compared to what was expected. There may be some glitches with spaces and %s 46 | - signature : binary(16) built with md5($name.'__'.$test['diff']) 47 | In URLs, the binary md5 is transformed as base64 (like 03410e89b1d2737ce178a795f298ae64). 48 | It is used to track differencies between each failed test in DB : we compare only the signature, 49 | which is simpler than checking every diff. 50 | 51 | 52 | When do we have new reports ? 53 | ----------------------------- 54 | When you do a 'make test' on your PHP sourcedir, you can send a report when something went wrong. 55 | If you do this, the test program will build a flat file containing all failed tests output/diff 56 | and send it to https://qa.php.net/buildtest-process.php (via POST method). 57 | Previously, this page only sent the report to a dedicated mailing list (qa-reports at lists.php.net). 58 | We now add a parser that intercept the data and send it to the function located in 59 | reports/parserfunc.php:parse_phpmaketest() 60 | This function transforms (with much regexp) the data (a big string in php format) to an array. 61 | This array is then given to reports/parserfunc.php:insertToDb_phpmaketest() that insert it to the 62 | sqlite file for this PHP version. 63 | 64 | 65 | What's planned ? 66 | ---------------- 67 | So much to do... and so little time (Batman). Please take a look at todo.txt 68 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 10 |

Welcome to the PHP Quality Assurance Team Web Page.

11 |

12 | The PHP Quality Assurance Team supports the PHP Development Team by 13 | providing them with information on compatibility and stability issues. 14 |

15 | 16 |

Make test results:

17 | 23 | 24 |

Available QA Releases:

25 | 26 |

27 |
28 | Windows users: 29 | See here for the Windows QA builds and 30 | here for the Windows Snapshot builds. 31 |

32 | 33 |

How To Help

34 |

35 | If you would like to contribute to these efforts, please 36 | visit our How To Help page. 37 |

38 | \n"; 47 | 48 | if (!empty($QA_RELEASES['releases'])) { 49 | 50 | $plural = count($QA_RELEASES['releases']) > 1 ? 's' : ''; 51 | 52 | // QA Releases 53 | echo "\n"; 54 | echo "Providing QA for the following test release{$plural}:

\n"; 55 | echo "
\n"; 56 | echo "\n"; 57 | 58 | foreach ($QA_RELEASES['releases'] as $pversion => $info) { 59 | 60 | echo "\n"; 61 | echo "\n"; 64 | echo "\n"; 65 | 66 | foreach ($info['files'] as $file_type => $file_info) { 67 | echo "\n"; 68 | echo "\n"; 69 | 70 | foreach ($QA_CHECKSUM_TYPES as $algo) { 71 | echo '\n"; 81 | } 82 | 83 | echo "\n"; 84 | } 85 | } 86 | 87 | echo "
\n"; 62 | echo "

{$info['version']}

\n"; 63 | echo "
php-{$info['version']}.tar.{$file_type}'; 72 | echo '' . strtoupper($algo) . ': '; 73 | 74 | if (isset($file_info[$algo]) && strlen($file_info[$algo])) { 75 | echo $file_info[$algo]; 76 | } else { 77 | echo '(No checksum value available) '; 78 | } 79 | 80 | echo "
\n"; 88 | } else { 89 | echo "There are no QA releases available at the moment to test."; 90 | } 91 | 92 | echo "\n"; 93 | } 94 | -------------------------------------------------------------------------------- /projects.php: -------------------------------------------------------------------------------- 1 | 11 |

PHP-QAT Goals

12 |

Release Candidates Testing and QA

13 | 19 |

Modify The Bug Database Interface

20 |

The interface should:

21 | 27 |

Bug Hunting

28 | 34 |

Provide Client-Side Bug Reporting via PHP Interpreter

35 | 52 | 56 | -------------------------------------------------------------------------------- /sample_tests/sample025.php: -------------------------------------------------------------------------------- 1 | 9 | 10 |
11 |

Sample Test: sample025.phpt

12 |

Back to "PHPT Test File Layout"

13 |
--TEST--
14 | Test imap_append() function : basic functionality
15 | --SKIPIF--
16 | <?php
17 | require_once(__DIR__.'/skipif.inc');
18 | ?>
19 | --FILE--
20 | <?php
21 | /* Prototype  : bool imap_append  ( resource $imap_stream  , string $mailbox  , string $message  [, string $options  ] )
22 |  * Description: Append a string message to a specified mailbox.
23 |  * Source code: ext/imap/php_imap.c
24 |  */
25 | 
26 | echo "*** Testing imap_append() : basic functionality ***\n";
27 | 
28 | require_once(__DIR__.'/imap_include.inc');
29 | 
30 | echo "Create a new mailbox for test\n";
31 | $imap_stream = setup_test_mailbox("", 0);
32 | if (!is_resource($imap_stream)) {
33 | 	exit("TEST FAILED: Unable to create test mailbox\n");
34 | }
35 | 
36 | $mb_details = imap_mailboxmsginfo($imap_stream);
37 | echo "Add a couple of msgs to new mailbox " . $mb_details->Mailbox . "\n";
38 | var_dump(imap_append($imap_stream, $mb_details->Mailbox
39 |                    , "From: webmaster@something.com\r\n"
40 |                    . "To: info@something.com\r\n"
41 |                    . "Subject: Test message\r\n"
42 |                    . "\r\n"
43 |                    . "this is a test message, please ignore\r\n"
44 |                    ));
45 | 
46 | var_dump(imap_append($imap_stream, $mb_details->Mailbox
47 |                    , "From: webmaster@something.com\r\n"
48 |                    . "To: info@something.com\r\n"
49 |                    . "Subject: Another test\r\n"
50 |                    . "\r\n"
51 |                    . "this is another test message, please ignore it too!!\r\n"
52 |                    ));
53 | 
54 | $check = imap_check($imap_stream);
55 | echo "Msg Count after append : ". $check->Nmsgs . "\n";
56 | 
57 | echo "List the msg headers\n";
58 | var_dump(imap_headers($imap_stream));
59 | 
60 | imap_close($imap_stream);
61 | ?>
62 | --CLEAN--
63 | <?php
64 | require_once('clean.inc');
65 | ?>
66 | --EXPECTF--
67 | *** Testing imap_append() : basic functionality ***
68 | Create a new mailbox for test
69 | Create a temporary mailbox and add 0 msgs
70 | .. mailbox '%s' created
71 | Add a couple of msgs to new mailbox {%s}INBOX.%s
72 | bool(true)
73 | bool(true)
74 | Msg Count after append : 2
75 | List the msg headers
76 | array(2) {
77 |   [0]=>
78 |   string(%d) "%w%s       1)%s webmaster@something. Test message (%d chars)"
79 |   [1]=>
80 |   string(%d) "%w%s       2)%s webmaster@something. Another test (%d chars)"
81 | }
82 | 
83 | 
84 |

Back to "PHPT Test File Layout"

85 |
86 | 87 | 90 | -------------------------------------------------------------------------------- /regtests/test/suite/bin/testscanf.php: -------------------------------------------------------------------------------- 1 | ") { 6 | if (is_array($val)) { 7 | for ($i = 0;$i< count($val);$i++) { 8 | echo $val[$i] . $postfix; 9 | } 10 | } else { 11 | echo $val . $postfix; 12 | } 13 | } 14 | 15 | function do_sscanf($string, $format) { 16 | $s = "sscanf(\"" . $string . ",\"" . $format ."\")."; 17 | echo "$s
"; 18 | $s = str_repeat("-", strlen($s)); 19 | echo "$s
"; 20 | $output = sscanf($string,$format); 21 | echo "Result : "; 22 | print_value( $output ); 23 | echo "$s

"; 24 | } 25 | 26 | 27 | function run_sscanf_test_cases() 28 | { 29 | global $testFileName; 30 | echo "


Running Test Cases from $testFileName

"; 31 | $arr = file( $testFileName ); 32 | for ($i=0;$i < count($arr);$i++) { 33 | $line_arr = explode("|",$arr[$i]); 34 | 35 | $format = $line_arr[0]; 36 | $string = $line_arr[1]; 37 | if (count($arr) > 2) { 38 | $comment = $line_arr[2]; 39 | } else { 40 | $comment = ""; 41 | } 42 | if ( empty($format) || empty($string) ) { 43 | continue; 44 | } 45 | print("

** Case : $comment ******************************

"); 46 | do_sscanf($string,$format); 47 | } 48 | } 49 | 50 | function simple_tests() { 51 | echo "Testing sscanf with standard ANSI syntax (values returned by 52 | reference)-
"; 53 | $decimal = -1; 54 | $string = ""; 55 | $hex = 0; 56 | $float = 0.0; 57 | $octal = 0.0; 58 | $int = -1; 59 | 60 | echo "


Simple Test

"; 61 | echo "sscanf('10','%d',&\$decimal)
"; 62 | echo "
BEFORE :
decimal = $decimal."; 63 | $foo = sscanf("10","%d",&$decimal); 64 | echo "
AFTER :
decimal = $decimal
"; 65 | 66 | 67 | echo "


Simple Test 2

"; 68 | echo "sscanf(\"ghost 0xface\",\"%s %x\",&\$string, &\$int)
"; 69 | echo "
BEFORE :
string = $string, int = $int
"; 70 | $foo = sscanf("ghost 0xface","%s %x",&$string, &$int); 71 | echo "
AFTER :
string = $string, int = $int
"; 72 | echo " sscan reports : "; 73 | print_value( $foo,""); 74 | echo " conversions
"; 75 | 76 | echo "


Multiple specifiers

"; 77 | echo "sscanf(\"jabberwocky 1024 0xFF 1.024 644 10\", 78 | \"%s %d %x %f %o %i\", 79 | &\$string,&\$decimal,&\$hex,&\$float,&\$octal,&\$int);
"; 80 | echo "
BEFORE :
"; 81 | echo "Decimal = $decimal, String = $string, Hex = $hex
"; 82 | echo "Octal = $octal , Float = $float, Int = $int
"; 83 | $foo = sscanf( "jabberwocky 1024 0xFF 1.024 644 10", 84 | "%s %d %x %f %o %i", 85 | &$string,&$decimal,&$hex,&$float,&$octal,&$int); 86 | echo "
AFTER :
"; 87 | echo "decimal = $decimal, string = $string, hex = $hex
"; 88 | echo "octal = $octal , float = $float, int = $int
"; 89 | 90 | echo " sscan reports : "; 91 | print_value( $foo,""); 92 | echo " conversions
"; 93 | echo "----------------------------------------
"; 94 | } 95 | 96 | 97 | 98 | 99 | if (!function_exists('sscanf')) { 100 | echo "I'm sorry but sscanf() does not exist !i
"; 101 | } else { 102 | simple_tests(); 103 | run_sscanf_test_cases(); 104 | } 105 | ?> 106 | -------------------------------------------------------------------------------- /pftt_report.php: -------------------------------------------------------------------------------- 1 | 20) { 69 | exit_error('Invalid revision'); 70 | } 71 | 72 | // validate report_file 73 | if ($_FILES['report_file']['size'] > 600000 or $_FILES['report_file']['size'] < 100 ) { 74 | // some PhpUnit reports can be quite large 75 | exit_error('Invalid report file size'); 76 | } else if ($_FILES['report_file']['type']!="text/html") { 77 | exit_error('Invalid report type'); 78 | } 79 | 80 | $file_contents = file_get_contents($_FILES['report_file']['tmp_name']); 81 | 82 | // validate file contents 83 | if (substr($file_contents, 0, 6)!="" or strpos($file_contents, "PFTT")===FALSE) { 84 | exit_error('Invalid report file content'); 85 | } 86 | 87 | // everything valid, now store it 88 | 89 | // cleanup report filename 90 | // will be named either: 91 | // PHPT_CMP_PHP_5_5-r31d67bd-NTS-X64-VC11_Local-FileSystem_CLI_v_PHP_5_5-rda84f3a-N.html 92 | // PhpUnit_CMP_PHP_5_5-r31d67bd-NTS-X64-VC11_Local-FileSystem_CLI_Symfony_v_PHP_5_5-rda84f3a-N.html 93 | // 94 | $report_name = trim($_FILES['report_file']['name']); 95 | if (strlen($report_name) > 100) { 96 | $report_name = substr($report_name, 0, 100); 97 | } 98 | if (substr($report_name, -5) != ".html") { 99 | $report_name .= ".html"; 100 | } 101 | 102 | // decide where to store it 103 | $report_file = dirname($_SERVER['SCRIPT_FILENAME']) . "/reports/db/$branch/$revision/$report_name"; 104 | $report_dir = dirname($report_file); 105 | 106 | // ensure dir exists 107 | mkdir($report_dir, 0777, TRUE); 108 | 109 | if ($fail_crash_count > 0) { 110 | $fh = fopen("$report_dir/FAIL_CRASH.txt", "w"); 111 | fwrite($fh, "$fail_crash_count"); 112 | fclose($fh); 113 | $fh = fopen("$$report_name.txt", "w"); 114 | fwrite($fh, "$fail_crash_count"); 115 | fclose($fh); 116 | } 117 | 118 | // report_file is stored locally in a temporary file, move that file to the permanent location 119 | move_uploaded_file($_FILES['report_file']['tmp_name'], $report_file); 120 | 121 | echo "Dir Content:"; 122 | var_dump(scandir($report_dir)); 123 | 124 | // done, successfully 125 | echo "Uploaded to $report_file"; 126 | 127 | ?> 128 | -------------------------------------------------------------------------------- /regtests/test/actuals/testscanf.out: -------------------------------------------------------------------------------- 1 | Testing sscanf with standard ANSI syntax (values returned by 2 | reference)-


Simple Test

sscanf('10','%d',&$decimal)

BEFORE :
decimal = -1.
AFTER :
decimal = 10


Simple Test 2

sscanf("ghost 0xface","%s %x",&$string, &$int)

BEFORE :
string = , int = -1

AFTER :
string = ghost, int = 64206
sscan reports : 2 conversions


Multiple specifiers

sscanf("jabberwocky 1024 0xFF 1.024 644 10", 3 | "%s %d %x %f %o %i", 4 | &$string,&$decimal,&$hex,&$float,&$octal,&$int);

BEFORE :
Decimal = 10, String = ghost, Hex = 0
Octal = 0 , Float = 0, Int = 64206

AFTER :
decimal = 1024, string = jabberwocky, hex = 255
octal = 420 , float = 1.024, int = 10
sscan reports : 6 conversions
----------------------------------------


Running Test Cases from ../../input/scan_cases

** Case : valid decimal (positive) 5 | ******************************

sscanf("48,"%d").
-----------------
Result : 48
-----------------

** Case : valid signed decimal (negative) 6 | ******************************

sscanf("-98,"%d").
------------------
Result : -98
------------------

** Case : integer scan : decimal digit followed by alpha 7 | ******************************

sscanf("56a,"%d").
------------------
Result : 56
------------------

** Case : decimal integer with width specification 8 | ******************************

sscanf("558071,"%4d").
----------------------
Result : 5580
----------------------

** Case : valid signed integer (negative) 9 | ******************************

sscanf("-5489,"%i").
--------------------
Result : -5489
--------------------

** Case : plain ole string matched with %s 10 | ******************************

sscanf(" the rain in spain ,"%s").
----------------------------------
Result : the
----------------------------------

** Case : string with width specifier 11 | ******************************

sscanf("jabberwocky,"%10s").
----------------------------
Result : jabberwock
----------------------------

** Case : valid float (%f) 12 | ******************************

sscanf("289.071,"%f").
----------------------
Result : 289.071
----------------------

** Case : valid negative (%f) 13 | ******************************

sscanf("-0.403,"%f").
---------------------
Result : -0.403
---------------------

** Case : Float with width specifier ending at decimal point 14 | ******************************

sscanf("76.4,"%3f").
--------------------
Result : 76
--------------------

** Case : Float with width specifier 15 | ******************************

sscanf("789.4,"%3f"").
----------------------
Result : 789
----------------------

** Case : octal with leading 0 16 | ******************************

sscanf("0321,"%o").
-------------------
Result : 209
-------------------

** Case : valid octal digits 17 | ******************************

sscanf("327,"%o").
------------------
Result : 215
------------------

** Case : octal scan with octal digit followed by non-octal 18 | ******************************

sscanf("380,"%o").
------------------
Result : 3
------------------

** Case : valid hex ******************************

sscanf("fe,"%x").
-----------------
Result : 254
-----------------

** Case : "c" style hex with leading 0x ******************************

sscanf("0xfe,"%x").
-------------------
Result : 254
-------------------

** Case : hex with all single digits < f 19 | ******************************

sscanf("455,"%x").
------------------
Result : 1109
------------------

** Case : hex (negative signed int) 20 | ******************************

sscanf("-98,"%x").
------------------
Result : -152
------------------

** Case : single char 21 | ******************************

sscanf("y,"%c").
----------------
Result : y
----------------

** Case : Character with width specification (4) 22 | ******************************

sscanf("tulips,"%4c").
----------------------
Result : tuli
----------------------

** Case : signed floating point with negative exponent 23 | ******************************

sscanf("10e-9,"%e").
--------------------
Result : 1E-08
--------------------

** Case : signed floating point with explicit positive exponent 24 | ******************************

sscanf("10e+9,"%e").
--------------------
Result : 10000000000
--------------------

** Case : signed floating point with positive exponent (no + sign) 25 | ******************************

sscanf("10e9,"%e").
-------------------
Result : 10000000000
-------------------

** Case : multiple specifiers 26 | ******************************

sscanf(" 19 84 0666 2000 0xface your x 31e+9 0.912 2.4 ," %d %i %o %u %x %s %c %e %f %g ").
-------------------------------------------------------------------------------------------
Result : 19
84
438
2000
64206
your
x
31000000000
0.912
2.4
-------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------- /regtests/test/ideals/testscanf.out: -------------------------------------------------------------------------------- 1 | Testing sscanf with standard ANSI syntax (values returned by 2 | reference)-


Simple Test

sscanf('10','%d',&$decimal)

BEFORE :
decimal = -1.
AFTER :
decimal = 10


Simple Test 2

sscanf("ghost 0xface","%s %x",&$string, &$int)

BEFORE :
string = , int = -1

AFTER :
string = ghost, int = 64206
sscan reports : 2 conversions


Multiple specifiers

sscanf("jabberwocky 1024 0xFF 1.024 644 10", 3 | "%s %d %x %f %o %i", 4 | &$string,&$decimal,&$hex,&$float,&$octal,&$int);

BEFORE :
Decimal = 10, String = ghost, Hex = 0
Octal = 0 , Float = 0, Int = 64206

AFTER :
decimal = 1024, string = jabberwocky, hex = 255
octal = 420 , float = 1.024, int = 10
sscan reports : 6 conversions
----------------------------------------


Running Test Cases from ../../input/scan_cases

** Case : valid decimal (positive) 5 | ******************************

sscanf("48,"%d").
-----------------
Result : 48
-----------------

** Case : valid signed decimal (negative) 6 | ******************************

sscanf("-98,"%d").
------------------
Result : -98
------------------

** Case : integer scan : decimal digit followed by alpha 7 | ******************************

sscanf("56a,"%d").
------------------
Result : 56
------------------

** Case : decimal integer with width specification 8 | ******************************

sscanf("558071,"%4d").
----------------------
Result : 5580
----------------------

** Case : valid signed integer (negative) 9 | ******************************

sscanf("-5489,"%i").
--------------------
Result : -5489
--------------------

** Case : plain ole string matched with %s 10 | ******************************

sscanf(" the rain in spain ,"%s").
----------------------------------
Result : the
----------------------------------

** Case : string with width specifier 11 | ******************************

sscanf("jabberwocky,"%10s").
----------------------------
Result : jabberwock
----------------------------

** Case : valid float (%f) 12 | ******************************

sscanf("289.071,"%f").
----------------------
Result : 289.071
----------------------

** Case : valid negative (%f) 13 | ******************************

sscanf("-0.403,"%f").
---------------------
Result : -0.403
---------------------

** Case : Float with width specifier ending at decimal point 14 | ******************************

sscanf("76.4,"%3f").
--------------------
Result : 76
--------------------

** Case : Float with width specifier 15 | ******************************

sscanf("789.4,"%3f"").
----------------------
Result : 789
----------------------

** Case : octal with leading 0 16 | ******************************

sscanf("0321,"%o").
-------------------
Result : 209
-------------------

** Case : valid octal digits 17 | ******************************

sscanf("327,"%o").
------------------
Result : 215
------------------

** Case : octal scan with octal digit followed by non-octal 18 | ******************************

sscanf("380,"%o").
------------------
Result : 3
------------------

** Case : valid hex ******************************

sscanf("fe,"%x").
-----------------
Result : 254
-----------------

** Case : "c" style hex with leading 0x ******************************

sscanf("0xfe,"%x").
-------------------
Result : 254
-------------------

** Case : hex with all single digits < f 19 | ******************************

sscanf("455,"%x").
------------------
Result : 1109
------------------

** Case : hex (negative signed int) 20 | ******************************

sscanf("-98,"%x").
------------------
Result : -152
------------------

** Case : single char 21 | ******************************

sscanf("y,"%c").
----------------
Result : y
----------------

** Case : Character with width specification (4) 22 | ******************************

sscanf("tulips,"%4c").
----------------------
Result : tuli
----------------------

** Case : signed floating point with negative exponent 23 | ******************************

sscanf("10e-9,"%e").
--------------------
Result : 1E-08
--------------------

** Case : signed floating point with explicit positive exponent 24 | ******************************

sscanf("10e+9,"%e").
--------------------
Result : 10000000000
--------------------

** Case : signed floating point with positive exponent (no + sign) 25 | ******************************

sscanf("10e9,"%e").
-------------------
Result : 10000000000
-------------------

** Case : multiple specifiers 26 | ******************************

sscanf(" 19 84 0666 2000 0xface your x 31e+9 0.912 2.4 ," %d %i %o %u %x %s %c %e %f %g ").
-------------------------------------------------------------------------------------------
Result : 19
84
438
2000
64206
your
x
31000000000
0.912
2.4
-------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------- /reports/details.php: -------------------------------------------------------------------------------- 1 | | 16 | # +----------------------------------------------------------------------+ 17 | 18 | $startTime = microtime(true); 19 | include "../include/functions.php"; 20 | include "../include/release-qa.php"; 21 | 22 | // sanitize 23 | if (!preg_match('@^[a-z0-9]{32}$@', $_GET['signature'])) { 24 | exit('Invalid signature'); 25 | } 26 | 27 | if (!is_valid_php_version($_GET['version'], $QA_RELEASES)) { 28 | exit('invalid version'); 29 | } 30 | 31 | $signature = $_GET['signature']; 32 | $version = $_GET['version']; 33 | 34 | $dbFile = __DIR__.'/db/'.$version.'.sqlite'; 35 | 36 | $database = new SQLite3($dbFile, SQLITE3_OPEN_READONLY); 37 | 38 | if (!$database) { 39 | die("Error opening DB file: ".$database->lastErrorMsg()); 40 | } 41 | 42 | // GET infos from DB 43 | $query = 'SELECT reports.* FROM failed JOIN reports ON reports.id=failed.id_report WHERE signature=:signature'; 44 | $stmt = $database->prepare($query); 45 | $stmt->bindValue(':signature', hex2bin($signature), SQLITE3_BLOB); 46 | $q = $stmt->execute(); 47 | $reportsArray = []; 48 | while ($tab = $q->fetchArray(SQLITE3_ASSOC)) { 49 | $reportsArray[$tab['id']] = $tab; 50 | } 51 | 52 | $query = 'SELECT test_name FROM failed WHERE signature=:signature LIMIT 1'; 53 | $stmt = $database->prepare($query); 54 | $stmt->bindValue(':signature', hex2bin($signature), SQLITE3_BLOB); 55 | $tab = $database->query($query); 56 | list($testName) = $tab->fetchArray(SQLITE3_NUM); 57 | 58 | // We stop everything 59 | $database->close(); 60 | 61 | $TITLE = "Report details"; 62 | $CURRENT_PAGE = "Reports"; 63 | common_header(['']); 64 | ?> 65 | 66 |
67 |

68 | 69 | List of reports associated

70 | Test name:
71 | Version: 72 |

73 | 78 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | '."\n"; 103 | echo ' '."\n"; 104 | echo ' '."\n"; 105 | if ($report['user_email'] == 'ciqa') { 106 | echo ' '."\n"; 107 | } else { 108 | echo ' '."\n"; 109 | } 110 | 111 | echo ' '."\n"; 113 | echo ' '."\n"; 114 | } 115 | 116 | ?> 117 | 118 | 119 | 122 |
123 |
124 | Goto: PHPInfo     Build environment
125 |
126 |

PHPInfo

';
130 |     echo htmlspecialchars($reportsArray[$idreport]['phpinfo'], ENT_QUOTES, 'UTF-8');
131 |     echo '

'; 132 | echo '

Build environment

';
133 |     echo htmlspecialchars(str_replace(
134 |         $reportsArray[$idreport]['user_email'],
135 |         '*** (truncated on purpose) ***',
136 |         $reportsArray[$idreport]['build_env']
137 |     ), ENT_QUOTES, 'UTF-8');
138 | 
139 | }
140 | 
141 | 
142 | echo '
'; 143 | $SITE_UPDATE = date('D M d H:i:s Y T', filemtime($dbFile)). 144 | "
Generated in ".round((microtime(true)-$startTime)*1000)." ms"; 145 | common_footer(); 146 | -------------------------------------------------------------------------------- /reports/parse_ciqa.php: -------------------------------------------------------------------------------- 1 | | 16 | # +----------------------------------------------------------------------+ 17 | # This file retrieve results from CI.QA and add them to QA report databases 18 | # 19 | # TODO : to handle "trunk", add |trunk to the first () in regexp line ~38 20 | # and update code about $QA_RELEASES at line ~143 21 | 22 | set_time_limit(0); 23 | 24 | header('Content-Type: text/plain'); 25 | $rss = new SimpleXMLElement('http://ci.qa.php.net/rssAll', 0, true); 26 | 27 | // get latest build done 28 | if (!file_exists('db/ciqaversion.txt')) { 29 | $latestVersion = []; 30 | } else { 31 | $latestVersion = unserialize(file_get_contents('db/ciqaversion.txt')); 32 | } 33 | $newLatestVersion = []; // this array will erase latestVersion at the end of the next loop 34 | 35 | // we grab builds in this array 36 | $buildArray = []; 37 | 38 | foreach ($rss->entry as $test) { 39 | $linkAttr = $test->link->attributes(); 40 | $z = preg_match('@http://ci.qa.php.net/job/php-src-([0-9\.]{3,})-matrix-build/' 41 | .'./architecture=([^/]{1,})/([0-9]{1,})@', (string) $linkAttr['href'], $pos); 42 | 43 | if (!$z) continue; 44 | 45 | // check if we already did this 46 | if (isset($latestVersion[ $pos[1] ]) && $latestVersion[ $pos[1] ] >= (int) $pos[3]) { 47 | continue; 48 | } 49 | 50 | 51 | $elem = [ 52 | 'id' => (int) $pos[3], 53 | 'date' => strtotime($test->updated), 54 | 'version' => $pos[1], 55 | 'archi' => $pos[2], 56 | 'url' => $pos[0], 57 | ]; 58 | //keep it ! 59 | $buildArray[] = $elem; 60 | 61 | // update what has been done so far 62 | if (!isset($newLatestVersion[ $pos[1] ]) || $newLatestVersion[ $pos[1] ] < $elem['id']) 63 | $newLatestVersion[ $pos[1] ] = $elem['id']; 64 | 65 | // stop at 5 reports (take time to parse) 66 | if (count($buildArray) == 5) break; 67 | } 68 | unset($rss); 69 | file_put_contents('db/ciqaversion.txt', serialize($newLatestVersion)); 70 | 71 | echo "We have ".count($buildArray)." builds to parse ... \n\n"; 72 | 73 | 74 | /*** 75 | * we do not add each report to QA (sqlite files will be too big) 76 | * We choose to pack them based on version parsed 77 | */ 78 | $failingTests = []; 79 | $successfulTests = []; 80 | 81 | foreach ($buildArray as $build) { 82 | printf(" * #%s (%5s) - %-30s ", $build['id'], $build['version'], $build['archi']); 83 | 84 | // retrieve and parse junit artefact 85 | $junitxml = new SimpleXMLElement($build['url'].'/artifact/junit.xml', 0, true); 86 | //$junitxml = new SimpleXMLElement('sample-junit.xml', LIBXML_NOCDATA, true); 87 | 88 | foreach ($junitxml->testsuite as $suite) { 89 | foreach ($suite->testsuite as $subsuite) { 90 | foreach ($subsuite->testcase as $case) { 91 | $attr = $case->attributes(); 92 | 93 | if (substr($attr['classname'], 0, 8) == 'php-src.') { 94 | $uri = '/'.str_replace('.', '/', substr($attr['classname'], 8)).'/'. 95 | substr($attr['name'], 0, strpos($attr['name'], '.phpt')+5); 96 | } else continue; 97 | 98 | // add it to array 99 | if (isset($case->failure)) { 100 | $fail = $case->failure->attributes(); 101 | 102 | if ($fail->type == 'FAILED') 103 | $failingTests[$build['version']][$uri] = trim( 104 | preg_replace( 105 | '@ [^\s]{1,}'.substr($uri, 0, -1).'@', 106 | ' %s/'.basename(substr($uri, 0, -1)), 107 | (string) $case->failure 108 | ) 109 | ); 110 | else { 111 | printf("ERROR: unknown failing type: ".$fail->type."\n"); 112 | continue; 113 | } 114 | } elseif (isset($case->skipped)) { 115 | // do nothing 116 | 117 | } else { 118 | // success 119 | $successfulTests[$build['version']][$uri] = true; 120 | } 121 | } 122 | } 123 | } 124 | unset($junitxml); // free memory 125 | 126 | printf("Success: %5s Fail: %5s (from all builds parsed)\n", 127 | count($successfulTests[$build['version']]), 128 | count($failingTests[$build['version']]) 129 | ); 130 | } 131 | 132 | // Add data ! 133 | echo "\n\nAdding data to databases ... \n"; 134 | require 'parserfunc.php'; 135 | require '../include/release-qa.php'; 136 | require '../include/functions.php'; 137 | 138 | foreach ($successfulTests as $version => $successTests) { 139 | echo "* ".$version." "; 140 | 141 | $firstArray = []; 142 | 143 | // determine status (success or failure ?) 144 | if (count($failingTests[$version]) == 0) 145 | $firstArray['status'] = 'success'; 146 | else 147 | $firstArray['status'] = 'failed'; 148 | 149 | // determine correct version 150 | // hard because we only have "5.4" and we know it's dev, so find next coming version ? 151 | foreach ($QA_RELEASES as $ver => $releaseData) { 152 | if (substr($ver, 0, strlen($version)) == $version) { 153 | $firstArray['version'] = $ver.'-dev'; 154 | break; 155 | } 156 | } 157 | 158 | if (!isset($firstArray['version'])) { 159 | // for trunk atm 160 | die('cannot determine version for '.$version); 161 | } 162 | 163 | // email 164 | $firstArray['userEmail'] = 'ciqa'; // magic value 165 | 166 | // date 167 | $firstArray['date'] = time(); 168 | 169 | $firstArray['phpinfo'] = ''; 170 | $firstArray['buildEnvironment'] = ''; 171 | 172 | // failed tests 173 | $firstArray['failedTest'] = array_keys($failingTests[$version]); 174 | 175 | // expected Failed Test 176 | $firstArray['expectedFailedTest'] = []; 177 | 178 | // success 179 | $firstArray['succeededTest'] = array_keys($successTests); 180 | 181 | // tests 182 | foreach ($failingTests[$version] as $test => $diff) { 183 | $firstArray['tests'][$test] = ['output' => '', 'diff' => str_replace("\n", "\x0d\n", $diff)]; 184 | } 185 | 186 | $status = insertToDb_phpmaketest($firstArray, $QA_RELEASES); 187 | if ($status === true) echo "SUCCESS !\n"; 188 | else echo " ERROR :( \n"; 189 | } 190 | -------------------------------------------------------------------------------- /running-tests.php: -------------------------------------------------------------------------------- 1 | 10 | 11 |

Test framework tests

12 | 13 |

The easiest way to test your PHP build is to run make test from 14 | the command line after successfully compiling. This will run the all tests for 15 | all enabled functionalities and extensions located in tests folders under the 16 | source root directory using the PHP CLI binary.

17 | 18 |

make test basically executes run-tests.php script 19 | under the source root (parallel builds will not work). Therefore you can execute 20 | the script as follows:

21 | 22 |
 23 | TEST_PHP_EXECUTABLE=sapi/cli/php \
 24 | sapi/cli/php [-c /path/to/php.ini] run-tests.php [ext/foo/tests/GLOB]
 25 | 
26 | 27 |

Which php executable does make test use?

28 | 29 |

If you are running the run-tests.php script from the command 30 | line (as above) you must set the TEST_PHP_EXECUTABLE environment 31 | variable to explicitly select the PHP executable that is to be tested, that is, 32 | used to run the test scripts.

33 | 34 |

If you run the tests using make test, the PHP CLI and CGI executables are 35 | automatically set for you. make test executes 36 | run-tests.php script with the CLI binary. Some test scripts such 37 | as session must be executed by CGI SAPI. Therefore, you must build PHP with CGI 38 | SAPI to perform all tests.

39 | 40 |

NOTE: PHP binary executing run-tests.php and php binary used for 41 | executing test scripts may differ. If you use different PHP binary for executing 42 | run-tests.php script, you may get errors. 43 | 44 |

Which php.ini is used?

45 | 46 |

make test uses the same php.ini file as it would once installed. 47 | The tests have been written to be independent of that php.ini file, so if you 48 | find a test that is affected by a setting, please report this, so we can address 49 | the issue.

50 | 51 |

Which test scripts are executed?

52 | 53 |

The run-tests.php (make test), without any arguments 54 | executes all test scripts by extracting all directories named tests 55 | from the source root and any subdirectories below. If there are files, which 56 | have a phpt extension, run-tests.php looks at the 57 | sections in these files, determines whether it should run it, by evaluating the 58 | SKIPIF section. If the test is eligible for execution, the 59 | FILE section is extracted into a .php file (with the 60 | same name besides the extension) and gets executed. When an argument is given or 61 | TESTS environment variable is set, the GLOB is expanded by the shell and any file 62 | with extension *.phpt is regarded as a test file.

63 | 64 |

Tester can easily execute tests selectively with as follows:

65 | 66 |
 67 | ./sapi/cli/php run-tests.php ext/mbstring/*
 68 | ./sapi/cli/php run-tests.php ext/mbstring/020.phpt
 69 | 
70 | 71 |

Test results

72 | 73 |

Test results are printed to standard output. If there is a failed test, the 74 | run-tests.php script saves the result, the expected result and the 75 | code executed to the test script directory. For example, if ext/myext/tests/myext.phpt 76 | fails to pass, the following files are created:

77 | 78 |
 79 | ext/myext/tests/myext.php   - actual test file executed
 80 | ext/myext/tests/myext.log   - log of test execution (L)
 81 | ext/myext/tests/myext.exp   - expected output (E)
 82 | ext/myext/tests/myext.out   - output from test script (O)
 83 | ext/myext/tests/myext.diff  - diff of .out and .exp (D)
 84 | 
85 | 86 |

Failed tests are always bugs. Either the test is bugged or not considering 87 | factors applying to the tester's environment, or there is a bug in PHP. If this 88 | is a known bug, we strive to provide bug numbers, in either the test name or the 89 | file name. You can check the status of such a bug, by going to: 90 | https://bugs.php.net/12345 where 12345 is the bug number. For clarity and 91 | automated processing, bug numbers are prefixed by a hash sign '#' in test names 92 | and/or test cases are named bug12345.phpt.

93 | 94 |

NOTE: The files generated by tests can be selected by setting the environment 95 | variable TEST_PHP_LOG_FORMAT. For each file you want to be generated use the 96 | character in brackets as shown above (default is LEOD). The php file will be 97 | generated always.

98 | 99 |

NOTE: You can set environment variable TEST_PHP_DETAILED to enable detailed 100 | test information.

101 | 102 |

Automated testing

103 | 104 |

If you like to keep up to speed, with latest developments and quality 105 | assurance, setting the environment variable NO_INTERACTION to 1, will not prompt 106 | the tester for any user input.

107 | 108 |

Normally, the exit status of make test is zero, regardless of 109 | the results of independent tests. Set the environment variable REPORT_EXIT_STATUS 110 | to 1, and make test will set the exit status ("$?") to non-zero, 111 | when an individual test has failed.

112 | 113 |

Example script to be run by cron:

114 | 115 |
116 | ========== qa-test.sh =============
117 | #!/bin/sh
118 | 
119 | CO_DIR=$HOME/cvs/php7
120 | MYMAIL=qa-test@domain.com
121 | TMPDIR=/var/tmp
122 | TODAY=`date +"%Y%m%d"`
123 | 
124 | # Make sure compilation environment is correct
125 | CONFIGURE_OPTS='--disable-all --enable-cli --with-pcre'
126 | export MAKE=gmake
127 | export CC=gcc
128 | 
129 | # Set test environment
130 | export NO_INTERACTION=1
131 | export REPORT_EXIT_STATUS=1
132 | 
133 | cd $CO_DIR
134 | cvs update . >>$TMPDIR/phpqatest.$TODAY
135 | ./cvsclean ; ./buildconf ; ./configure $CONFIGURE_OPTS ; $MAKE
136 | $MAKE test >>$TMPDIR/phpqatest.$TODAY 2>&1
137 | if test $? -gt 0
138 | then
139 |         cat $TMPDIR/phpqatest.$TODAY | mail -s"PHP-QA Test Failed for $TODAY" $MYMAIL
140 | fi
141 | ========== end of qa-test.sh =============
142 | 
143 | 144 |

NOTE: The exit status of run-tests.php will be 1 when 145 | REPORT_EXIT_STATUS is set. The result of make test may be higher 146 | than that. At present, gmake 3.79.1 returns 2, so it is advised to test for 147 | non-zero, rather then a specific value.

148 | 149 |

When make test finished running tests, and if there are any failed 150 | tests, the script asks to send the logs to the PHP QA mailinglist. Please answer 151 | y to this question so that we can efficiently process the results, 152 | entering your e-mail address (which will not be transmitted in plaintext to any 153 | list) enables us to ask you some more information if a test failed. Note that 154 | this script also uploads php -i output so your hostname may be 155 | transmitted.

156 | 157 |

158 | Specific tests can also be executed, like running tests for a certain extension. 159 | To do this you can do like so (for example the standard library): 160 | make test TESTS=ext/standard. Where TESTS= points to a 161 | directory containing .phpt files or a single .phpt file like: 162 | make test TESTS=tests/basic/001.phpt. You can also pass options directly 163 | to the underlaying script that runs the test suite (run-tests.phpt) using 164 | TESTS=, for example to check for memory leaks using Valgrind, the 165 | -m option can be passed along: make test TESTS="-m Zend/". 166 | For a full list of options that can be passed along, then run make test TESTS=-h. 167 |

168 | 169 |

170 | Windows users: On Windows the make command is called nmake 171 | instead of make. This means that on Windows you will have to run 172 | nmake test, to run the test suite. 173 |

174 | 175 | 178 | -------------------------------------------------------------------------------- /reports/viewreports.php: -------------------------------------------------------------------------------- 1 | | 16 | # +----------------------------------------------------------------------+ 17 | 18 | $startTime = microtime(true); 19 | include "../include/functions.php"; 20 | include "../include/release-qa.php"; 21 | 22 | // sanitize 23 | if (!preg_match('@^[a-zA-Z\.0-9\-_/]{1,}$@', $_GET['test'])) { 24 | exit('Invalid test'); 25 | } 26 | 27 | if (!is_valid_php_version($_GET['version'], $QA_RELEASES)) { 28 | exit('invalid version'); 29 | } 30 | 31 | $testName = $_GET['test']; 32 | $version = $_GET['version']; 33 | 34 | $dbFile = __DIR__.'/db/'.$version.'.sqlite'; 35 | $siteUpdate = date("D M d H:i:s Y T", filemtime($dbFile))."
\n"; 36 | $database = new SQLite3($dbFile, SQLITE3_OPEN_READONLY); 37 | 38 | if (!$database) { 39 | die("Error: Impossible to open, check permissions"); 40 | } 41 | 42 | // GET infos from DB 43 | $query = 'SELECT id,signature, COUNT(*) as cpt, output, diff FROM failed 44 | WHERE test_name=:test_name 45 | GROUP BY diff ORDER BY COUNT(*) desc'; 46 | $stmt = $database->prepare($query); 47 | $stmt->bindValue(':test_name', $testName, SQLITE3_TEXT); 48 | $q = $stmt->execute(); 49 | $allDiffArray = []; 50 | $sumCount = 0; 51 | while ($tab = $q->fetchArray(SQLITE3_ASSOC)) { 52 | $allDiffArray[] = $tab; 53 | $sumCount += $tab['cpt']; 54 | } 55 | // We stop everything 56 | $database->close(); 57 | 58 | 59 | 60 | //URL test 61 | $v = substr($version, 0, 3); 62 | $urlTest = "https://github.com/php/php-src/blob/PHP-$v/".ltrim($testName, '/'); 63 | 64 | // BUG url 65 | if (preg_match('@bug([0-9]{1,}).phpt$@', $testName, $preg)) { 66 | $bugId = (int)$preg[1]; 67 | $bugUrl = 'https://bugs.php.net/'.$preg[1]; 68 | } else { 69 | $bugId = null; 70 | $bugUrl = ''; 71 | } 72 | 73 | 74 | 75 | 76 | $TITLE = "Reports for test ".$testName; 77 | 78 | $CURRENT_PAGE = "Reports"; 79 | 80 | common_header(); 81 | ?> 82 | 83 |
84 |

85 | 87 | '; 91 | echo ' '; 92 | } 93 | if ($bugUrl != '') { 94 | echo '    '; 95 | echo ''; 96 | } 97 | ?>

98 | 99 | Failed loading bug info. SimpleXML: '.(extension_loaded("simplexml") ? 'Yes' : 'No').', OpenSSL: '.(extension_loaded("openssl") ? 'Yes' : 'No').'
'; 103 | } else { 104 | ?> 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 |
bug_type);?> #sdesc);?>
Submitted:ts1);?>Modified:ts2);?>
From:email, '@'));?>Assigned:assign); ?>
Status:status);?>Package:package_name);?>
PHP Version:php_version);?>OS:php_os);?>
136 | "; 139 | } 140 | ?> 141 | 142 | 143 | 152 | 153 |

154 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | \n '; 189 | echo "\n '."\n "; 205 | 206 | // Complete output will be available in the future (present in DB file) 207 | //echo ''; 208 | 209 | echo ''."\n"; 210 | echo ''; 211 | $i++; 212 | if ($i > 20) break; 213 | } 214 | ?> 215 |
CountDiff
".$diff['cpt'].' ('; 185 | echo round($diff['cpt']/$sumCount*100)."%)
"; 186 | echo ''; 188 | echo '
\n"; 190 | echo '
'; 191 | $diffExploded = explode("\x0d", $diff['diff']); 192 | foreach ($diffExploded as $line) { 193 | if (preg_match('@([0-9]{2,})(\-{1}) @', $line)) { 194 | echo '
'.htmlentities($line).'
'."\n"; 195 | 196 | } elseif (preg_match('@[0-9]{2,}[\+]{1,} @', $line)) { 197 | echo '
'.htmlentities($line).'
'."\n"; 198 | 199 | } else { 200 | // Should not happen. But print it anyway 201 | echo $line; 202 | } 203 | } 204 | echo '
View complete output
216 | 217 | ". 219 | " Generated in ".round((microtime(true)-$startTime)*1000)." ms"; 220 | common_footer(); 221 | -------------------------------------------------------------------------------- /include/release-qa.php: -------------------------------------------------------------------------------- 1 | [ 49 | 'active' => true, 50 | 'release' => [ 51 | 'type' => 'RC', 52 | 'number' => 0, 53 | 'sha256_gz' => '', 54 | 'sha256_bz2' => '', 55 | 'sha256_xz' => '', 56 | 'date' => '07 Nov 2023', 57 | 'baseurl' => 'https://downloads.php.net/', 58 | ], 59 | ], 60 | 61 | '8.2.27' => [ 62 | 'active' => true, 63 | 'release' => [ 64 | 'type' => 'RC', 65 | 'number' => 0, 66 | 'sha256_bz2' => '', 67 | 'sha256_gz' => '', 68 | 'sha256_xz' => '', 69 | 'date' => '05 Dec 2024', 70 | 'baseurl' => 'https://downloads.php.net/', 71 | ], 72 | ], 73 | 74 | '8.3.21' => [ 75 | 'active' => true, 76 | 'release' => [ 77 | 'type' => 'RC', 78 | 'number' => 1, 79 | 'sha256_bz2' => 'c86adcc8918da561038d671009acb6223fb6ed2263ad6139711674be94ac60a4', 80 | 'sha256_gz' => 'b0da1f161a247e83c8c4fcd5b71b1a42a9fcd26d129404955f70fd986c026559', 81 | 'sha256_xz' => '6d8bf25e0584cfcb83243fd7d1a90c06d428f1204eea93bb3c027c6e3344a23e', 82 | 'date' => '24 Apr 2025', 83 | 'baseurl' => 'https://downloads.php.net/~eric/', 84 | ], 85 | ], 86 | 87 | '8.4.7' => [ 88 | 'active' => true, 89 | 'release' => [ 90 | 'type' => 'RC', 91 | 'number' => 1, 92 | 'sha256_bz2' => 'acddb1da1b128f984df01347c907a64939f316d7d9bd138b49106f4179b7776f', 93 | 'sha256_gz' => 'b12d97767aeda4624ea1904c1d93303efe4ffe1ba91970a3c5774ad556918e93', 94 | 'sha256_xz' => '6cb37632eb65ee311cb4427ad070b6ab27fdaf13e8f0103701b2b78907326c93', 95 | 'date' => '24 Apr 2025', 96 | 'baseurl' => 'https://downloads.php.net/~saki/', 97 | ], 98 | ], 99 | ]; 100 | 101 | /*** End Configuration *******************************************************************/ 102 | 103 | // This is a list of the possible checksum values that can be supplied with a QA release. Any 104 | // new algorithm is read from the $QA_RELEASES array under the 'release' index for each version 105 | // in the form of "$algorithm_$filetype". 106 | // 107 | // For example, if SHA512 were to be supported, the following indices would have to be added: 108 | // 109 | // 'sha512_bz2' => 'xxx', 110 | // 'sha512_gz' => 'xxx', 111 | // 'sha512_xz' => 'xxx', 112 | $QA_CHECKSUM_TYPES = ['sha256']; 113 | 114 | // $QA_RELEASES eventually contains just about everything, also for external use 115 | // release : These are encouraged for use (e.g., linked at qa.php.net) 116 | // reported : These are allowed to report @ the php.qa.reports mailing list 117 | 118 | (function(&$QA_RELEASES) use ($QA_CHECKSUM_TYPES) { 119 | foreach ($QA_RELEASES as $pversion => $info) { 120 | 121 | if (isset($info['active']) && $info['active']) { 122 | 123 | // Allow -dev versions of all active types 124 | // Example: 5.3.6-dev 125 | $QA_RELEASES['reported'][] = "{$pversion}-dev"; 126 | $QA_RELEASES[$pversion]['dev_version'] = "{$pversion}-dev"; 127 | 128 | // Allow -dev version of upcoming qa releases (rc/alpha/beta) 129 | // @todo confirm this php version format for all dev versions 130 | if ((int)$info['release']['number'] > 0) { 131 | $QA_RELEASES['reported'][] = "{$pversion}{$info['release']['type']}{$info['release']['number']}"; 132 | if (!empty($info['release']['baseurl'])) { 133 | 134 | // php.net filename format for qa releases 135 | // example: php-5.3.0RC2 136 | $fn_base = 'php-' . $pversion . $info['release']['type'] . $info['release']['number']; 137 | 138 | $QA_RELEASES[$pversion]['release']['version'] = $pversion . $info['release']['type'] . $info['release']['number']; 139 | foreach ([ 'bz2', 'gz', 'xz' ] as $file_type) { 140 | foreach ($QA_CHECKSUM_TYPES as $algo) { 141 | if (isset($info['release'][$algo . '_' . $file_type])) { 142 | $QA_RELEASES[$pversion]['release']['files'][$file_type][$algo] = $info['release'][$algo . '_' . $file_type]; 143 | } 144 | } 145 | if (!empty($QA_RELEASES[$pversion]['release']['files'][$file_type])) { 146 | $QA_RELEASES[$pversion]['release']['files'][$file_type]['path']= $info['release']['baseurl'] . $fn_base . '.tar.' . $file_type; 147 | } 148 | } 149 | 150 | if (empty($QA_RELEASES[$pversion]['release']['files'])) { 151 | $QA_RELEASES[$pversion]['release']['enabled'] = false; 152 | } 153 | } 154 | } else { 155 | $QA_RELEASES[$pversion]['release']['enabled'] = false; 156 | } 157 | 158 | } 159 | } 160 | 161 | // Sorted information for later use 162 | // @todo need these? 163 | // $QA_RELEASES['releases'] : All current versions with active qa releases 164 | foreach ($QA_RELEASES as $pversion => $info) { 165 | if (isset($info['active']) && $info['active'] && !empty($info['release']['number'])) { 166 | $QA_RELEASES['releases'][$pversion] = $info['release']; 167 | } 168 | } 169 | 170 | })($QA_RELEASES); 171 | -------------------------------------------------------------------------------- /handling-bugs.php: -------------------------------------------------------------------------------- 1 | 11 |

Handling bug reports?

12 |

Introduction

13 | 14 |

15 | Welcome to the HOWTO on managing PHP bugs via bugs.php.net. PHP is a large project with many 17 | bugs being submitted daily. Bug topics range from the PHP website itself, 18 | various PHP extensions, PEAR, etc. This document is for all PHP developers 19 | using the bug system. Because there are so many members using the system it's 20 | important we act in a consistent manner. This HOWTO is created to solve this. 21 |

22 | 23 |

If you're going to edit a bug be sure that you know the topic. Don't make 24 | assumptions. If you've read the bug carefully and think of a solution or 25 | related questions, post your answer/comments. If you know of the solution, 26 | solve and close the bug.

27 | 28 |

Acting on a bug

29 | 30 |

Never change a status if you're not sure. If you close a bug because you 31 | think it's not really a bug and in fact it is, this makes the bug system 32 | useless and doesn't benefit anyone. Never close a bug because it's too old, 33 | unless your name is Jani. If a bug is in "feedback" status it will close 34 | automatically if the bug reporter doesn't answer after two weeks.

35 | 36 |

If you want to view a bug report, enter the bug id into the url like 37 | so (with 20406 being an example):

38 | 39 | 44 | 45 |

Which redirects to:

46 | 47 | 52 | 53 |

At that point you'll see a set of options. Because you're a developer you 54 | will choose the developer option which will then put you here:

55 | 56 | 61 | 62 |

Automatic answers (quickfix)

63 | 64 |

There are a set of quickfix options each of which will both insert text into 65 | the bug report and change the bug status. Please understand what text and 66 | status will be used and only choose a quickfix option if an appropriate 67 | quickfix exists. Choosing a quickfix that's not 100% correct will confuse 68 | and sometimes irritate the reporter. The following table lists them (see 69 | also quick-fix-desc.php):

70 | 71 | 72 |

Manual answers

73 | 74 |

If no quickfix is available you will manually choose the new status and 75 | write some feedback. Select the best status that corresponds to the bug. 76 | Here are descriptions for each status:

77 | 78 |

79 |

80 |
Open
81 |
82 | The bug still exists and you want to comment on it. 83 |
84 | 85 |
Closed
86 |
87 | It has been fixed. If you choose this please make sure 88 | it's also been documented. Also, explain why it's closed. 89 |
90 | 91 |
Duplicate
92 |
93 | This status is deprecated and can no longer be selected during 94 | modifications of bugs. Always use "Not a Bug" instead now. The originial 95 | use was: 96 | If this almost the same bug, both bugs are found 'duplicate' later 97 | on and have both useful information. Also mention what bug it's a 98 | duplicate of with a full url to the report this is duplicate of. 99 |
100 | 101 |
Critical
102 |
103 | Only bugs that affect most/all users and/or are in the engine or 104 | ext/standard. Only Verified and reproduced bugs in the latest 105 | Git revision can be marked critical. 106 |
107 | 108 |
Assigned
109 |
110 | If a specific person, such as yourself, will take of this bug then 111 | assign it. If you know someone else is or will take care of it then assign 112 | it to them but be sure to ask them first. 113 |
114 | 115 |
Analyzed
116 |
117 | If you've analyzed why this bug is here and know why the bug exists, you 118 | have just analyzed it. Also, add a comment. If you are unsure why it 119 | exists then use 'verified' instead. 120 |
121 | 122 |
Verified
123 |
124 | If you're able to reproduce this bug with the information given. 125 | Be sure to test with the latest Git. Typically you aren't sure why 126 | it exists you just know it does and have confirmed it. 127 |
128 | 129 |
Suspended
130 |
131 | Usually used when there might be a fix in future and/or it relies on 132 | something external to be fixed first. 133 |
134 | 135 |
Wont fix
136 |
When something is not considered a bug or the bug is not fixable.
137 | 138 |
No feedback
139 |
140 | If no answer have been given by the reporter after we've asked them 141 | something. Sometimes you will ask for an example script or ask the 142 | reporter to test using Git. 143 |
144 | 145 |
Feedback
146 |
147 | You're asking the reporter for more information such as please use 148 | Git revision, and/or the smallest possible test script to reproduce the 149 | error, and/or a value for a certain PHP directive. 150 |
151 | 152 |
Not a Bug (old: Bogus)
153 |
154 | This bug is not a bug, support related or just an assumed bug or the 155 | bug already exists in the database. Be 100% it's really "bogus" and 156 | also be sure it's not a documentation bug. 157 |
158 |
159 | 160 |

Reclassification

161 | 162 |

Sometimes you'll also want to reclassify a bug. For example, a reporter 163 | marks a bug as Apache2 related when really it's a MySQL bug. Just change 164 | the category but be 100% sure it's related to the new category. Another 165 | example would be changing the type to a documentation bug. If you're 166 | changing it to a documentation bug it will help the documentation team if you 167 | add specific information that is to be documented including what version the 168 | changes will take place.

169 | 170 |

Also note that all bugs are sent to various mailing lists with 171 | php-bugs@lists.php.net being the default (most go here). Here's a list:

172 | 173 |
174 |
Default
175 |
php-bugs@lists.php.net
176 | 177 |
Documentation
178 |
phpdoc@lists.php.net
179 | 180 |
PEAR
181 |
pear-dev@lists.php.net
182 | 183 |
PHP.net Website
184 |
php-mirrors@lists.php.net
185 |
186 | 187 |

Reclassifying will immediatly change which mailing list is used. If you 188 | reclassify a bug and don't leave a comment then no email is sent to the mailing list. 189 | So, be sure to leave a comment.

190 | 191 |

Tips and links

192 | 215 | 216 |

Conclusion

217 | 218 |

If everyone maintains the bug system in a consistent manner then PHP will 219 | be better for it. Also, bug reporters will not get their feelings hurt 220 | through miscommunication (e.g. a wrong quickfix or bogus status) Thank you 221 | for reading this HOWTO and helping make PHP better.

222 |
223 | 227 | -------------------------------------------------------------------------------- /reports/reportsfunctions.php: -------------------------------------------------------------------------------- 1 | | 16 | # | Johannes Schlüter | 17 | # +----------------------------------------------------------------------+ 18 | 19 | class QaReportIterator extends FilterIterator 20 | { 21 | public function __construct(DirectoryIterator $inner) 22 | { 23 | parent::__construct($inner); 24 | } 25 | 26 | public function accept() 27 | { 28 | return substr(parent::current(), -7) == '.sqlite'; 29 | } 30 | 31 | public function key() 32 | { 33 | return substr(parent::current(), 0, -7); 34 | } 35 | 36 | public function current() 37 | { 38 | return __DIR__.'/db/'.parent::current(); 39 | } 40 | } 41 | 42 | abstract class WhitelistedFilterIterator extends FilterIterator 43 | { 44 | private $whitelist; 45 | 46 | public function __construct(Traversable $inner, array $whitelist) 47 | { 48 | parent::__construct($inner); 49 | $this->whitelist = $whitelist; 50 | } 51 | 52 | public function inWhitelist() 53 | { 54 | return in_array($this->key(), $this->whitelist); 55 | } 56 | } 57 | 58 | class keywordFilterIterator extends WhitelistedFilterIterator 59 | { 60 | private $keyword; 61 | 62 | public function __construct(Traversable $inner, $keyword, array $whitelist) 63 | { 64 | parent::__construct($inner, $whitelist); 65 | $this->keyword = preg_quote($keyword, ','); 66 | } 67 | 68 | public function accept() 69 | { 70 | return $this->inWhitelist() || !preg_match(','.$this->keyword.'[0-9]+$,', $this->key()); 71 | } 72 | } 73 | 74 | class devFilterIterator extends WhitelistedFilterIterator 75 | { 76 | public function accept() 77 | { 78 | return $this->inWhitelist() || substr($this->key(), -4) != '-dev'; 79 | } 80 | } 81 | 82 | class specificVersionFilterIterator extends WhitelistedFilterIterator 83 | { 84 | private $keyword; 85 | 86 | public function __construct(Traversable $inner, $keyword) 87 | { 88 | parent::__construct($inner, []); 89 | if (!is_array($keyword)) 90 | $this->keyword = [$keyword]; 91 | else 92 | $this->keyword = $keyword; 93 | } 94 | 95 | public function accept() 96 | { 97 | return $this->inWhitelist() || !in_array($this->key(), $this->keyword); 98 | } 99 | } 100 | 101 | class minVersionFilterIterator extends FilterIterator 102 | { 103 | private $min; 104 | 105 | public function __construct(Traversable $inner, $minversion) 106 | { 107 | parent::__construct($inner); 108 | $this->min = $minversion; 109 | } 110 | 111 | public function accept() 112 | { 113 | return version_compare($this->min, $this->key(), '<='); 114 | } 115 | } 116 | 117 | const QA_REPORT_FILTER_NONE = 0; 118 | const QA_REPORT_FILTER_ALPHA = 1; 119 | const QA_REPORT_FILTER_BETA = 2; 120 | const QA_REPORT_FILTER_RC = 4; 121 | const QA_REPORT_FILTER_DEV = 8; 122 | const QA_REPORT_FILTER_CURRENT_RELEASES = 16; 123 | 124 | define('QA_REPORT_FILTER_ALL', QA_REPORT_FILTER_ALPHA|QA_REPORT_FILTER_BETA|QA_REPORT_FILTER_CURRENT_RELEASES); 125 | 126 | /** 127 | * Analyse sqlite files and retrieve data from it 128 | * @return array 129 | */ 130 | function get_summary_data($mode = QA_REPORT_FILTER_ALL) 131 | { 132 | global $QA_RELEASES; 133 | 134 | $data = []; 135 | $it = new QaReportIterator(new DirectoryIterator(__DIR__.'/db/')); 136 | 137 | // temp fix 138 | $it = new specificVersionFilterIterator($it, ['5.3.99-dev', '5.4.0-dev']); 139 | 140 | if ($mode & QA_REPORT_FILTER_ALPHA) { 141 | $it = new keywordFilterIterator($it, 'alpha', $QA_RELEASES['reported']); 142 | } 143 | if ($mode & QA_REPORT_FILTER_BETA) { 144 | $it = new keywordFilterIterator($it, 'beta', $QA_RELEASES['reported']); 145 | } 146 | if ($mode & QA_REPORT_FILTER_RC) { 147 | $it = new keywordFilterIterator($it, 'RC', $QA_RELEASES['reported']); 148 | } 149 | if ($mode & QA_REPORT_FILTER_DEV) { 150 | $it = new devFilterIterator($it, $QA_RELEASES['reported']); 151 | } 152 | if ($mode & QA_REPORT_FILTER_CURRENT_RELEASES) { 153 | $it = new minVersionFilterIterator($it, "5.3.14"); 154 | } 155 | 156 | 157 | foreach ($it as $version => $database_file) { 158 | if (!file_exists($database_file.'.cache') || 159 | !($dataSerialize = unserialize(file_get_contents($database_file.'.cache')))) { 160 | 161 | $database = new SQLite3($database_file, SQLITE3_OPEN_READONLY); 162 | //retrieve data 163 | $query = $database->query( 164 | "SELECT COUNT(*) AS nbReports, MAX(`date`) AS lastReport FROM reports" 165 | ); 166 | if (!$query) 167 | die("An error occured when reading summary data from $version DB file."); 168 | $row = $query->fetchArray(SQLITE3_ASSOC); 169 | $data[$version] = $row; 170 | 171 | $query = $database->query( 172 | "select count(distinct test_name) as nbFailingTests, count(*) as nbFailures from failed" 173 | ); 174 | if (!$query) 175 | die("An error occured when reading failingTest data from $version DB file."); 176 | $row = $query->fetchArray(SQLITE3_ASSOC); 177 | $data[$version]['nbFailingTests'] = $row['nbFailingTests']; 178 | $data[$version]['nbFailures'] = $row['nbFailures']; 179 | 180 | $database->close(); 181 | // write cache data 182 | file_put_contents($database_file.'.cache', serialize($data[$version])); 183 | } else { 184 | $data[$version] = $dataSerialize; 185 | } 186 | } 187 | return $data; 188 | } 189 | 190 | 191 | /** 192 | * Format date as we want 193 | * @param unix timestamp 194 | * @return string 195 | */ 196 | function format_readable_date($date) { 197 | $lastReport = time()-$date; 198 | $return = ''; 199 | if ($lastReport < 3600) { 200 | $tmpValue = round($lastReport/60); 201 | $return = $tmpValue.' '; 202 | $return .= ($tmpValue <= 1) ? 'minute' : 'minutes'; 203 | } elseif ($lastReport < 3600*24) { 204 | $tmpValue = round($lastReport/3600); 205 | $return = $tmpValue.' '; 206 | $return .= ($tmpValue == 1) ? 'hour' : 'hours'; 207 | } elseif ($lastReport < 3600*24*60) { 208 | $tmpValue = round($lastReport/3600/24); 209 | $return = $tmpValue.' '; 210 | $return .= ($tmpValue == 1) ? 'day' : 'days'; 211 | } else { 212 | $tmpValue = floor($lastReport/3600/24/30); 213 | $return = $tmpValue.' '; 214 | $return .= ($tmpValue == 1) ? 'month' : 'months'; 215 | } 216 | return $return." ago"; 217 | } 218 | 219 | // In a report/ or pfft script, the 'branch' parameter 220 | // takes the form PHP_{$major}_{$minor} (i.e. PHP_7_2) 221 | // or PHP_MASTER, indicating the current master branch 222 | function isValidBranch(string $branch, bool $verifyExists = true): bool { 223 | return ($branch === 'PHP_MASTER') || 224 | preg_match('@^PHP_\d{1,10}_\d{1,10}$@', $branch); 225 | } 226 | 227 | // In a report/ or pftt script, the 'revision' parameter 228 | // may be either the letter 'r' followed by hexits, 229 | // indicating a GIT hash (or possibly a SVN revision?) 230 | // Or they may be a release version (e.g. '7.2.9', '7.3.0-beta2') 231 | function isValidRevision(string $revision): bool { 232 | // 41 characters ought to be enough for any revision (haha) 233 | if ((strlen($revision) < 1) || (strlen($revision) > 41)) { 234 | return false; 235 | } 236 | 237 | // Allow r(HEXIT+) form. 238 | if (($revision[0] === 'r') && ctype_xdigit(substr($revision, 1))) { 239 | return true; 240 | } 241 | 242 | // Allow release version form. 243 | if (preg_match('@^\d+\.\d+\.\d+(-alpha\d+|-beta\d+|RC\d+|-dev)?$@i', $revision)) { 244 | return true; 245 | } 246 | 247 | return false; 248 | } 249 | 250 | // Generate a path from a branch name 251 | function makeBranchPath(string $branch) /* : ?sting */ { 252 | if (!isValidBranch($branch)) return null; 253 | return __DIR__ . "/db/$branch/"; 254 | } 255 | 256 | // Generate a path from a branch and revision 257 | function makeRevisionPath(string $branch, string $revision) /* : ?string */ { 258 | $path = makeBranchPath($branch); 259 | if (($path === null) || !isValidRevision($revision)) { return false; } 260 | return "$path/$revision/"; 261 | } 262 | -------------------------------------------------------------------------------- /reports/test-insert.php: -------------------------------------------------------------------------------- 1 | | 16 | # +----------------------------------------------------------------------+ 17 | 18 | header('HTTP/1.0 403 Forbidden'); 19 | die('This script is for local testing purposes only! Uncomment these lines to use it.'); 20 | 21 | error_reporting(E_ALL); 22 | 23 | require 'parserfunc.php'; 24 | require '../include/functions.php'; 25 | echo '

Testing QA report parsing and database handling

'; 26 | echo '
'."\n";
 27 | 
 28 | $str = file_get_contents('sample.txt');
 29 | echo 'Content length: '.strlen($str);
 30 | if (strlen($str) == 126341) echo " OK \n";
 31 | else                        echo " KO (value: ".strlen($str)." \n";
 32 | echo "Parsing with function parse_phpmaketest() ... \n";
 33 | $array = parse_phpmaketest('5.3.7-dev', 'failed', $str);
 34 | 
 35 | printf("%-30s", "Result should be array: ");
 36 | if (is_array($array)) echo " OK \n";
 37 | else                        echo " KO \n";
 38 | 
 39 | printf("%-30s", "Version extracted match: ");
 40 | if ($array['version'] == '5.3.7-dev') echo " OK \n";
 41 | else                        echo " KO. value extracted: ".$array['version']." \n";
 42 | 
 43 | printf("%-30s", "Test email match: ");
 44 | if ($array['userEmail'] == 'thisisatestmail@testdomain.com') echo " OK \n";
 45 | else                        echo " KO. value extracted: ".$array['userEmail']." \n";
 46 | 
 47 | printf("%-30s", "extract 17 expectedFailedTest");
 48 | if (count($array['expectedFailedTest']) == 17) echo " OK \n";
 49 | else                        echo " KO \n";
 50 | 
 51 | printf("%-30s", "extract 33 failedTest");
 52 | if (count($array['failedTest']) == 33) echo " OK \n";
 53 | else                        echo " KO \n";
 54 | 
 55 | printf("%-30s", "33 detailed test");
 56 | if (count($array['tests']) == 33) echo " OK \n";
 57 | else                        echo " KO \n";
 58 | 
 59 | printf("%-30s", "specific expectedFailedTest");
 60 | if (in_array('Zend/tests/bug48770_3.phpt', $array['expectedFailedTest'])) echo " OK \n";
 61 | else                        echo " KO \n";
 62 | 
 63 | printf("%-30s", "specific failedTest");
 64 | if (in_array('ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt', $array['failedTest']))
 65 |      echo " OK \n";
 66 | else echo " KO \n";
 67 | 
 68 | printf("%-30s", "specific test diff");
 69 | $strlen = strlen($array['tests']['/tests/func/010.phpt']['diff']);
 70 | if (isset($array['tests']['/tests/func/010.phpt']['diff']) && $strlen >= 290 )
 71 |      echo " OK size:   ".$strlen." - optimal =   293 \n";
 72 | else echo " KO (length: $strlen should be > 290) \n";
 73 | 
 74 | printf("%-30s", "specific test output");
 75 | $strlen = strlen($array['tests']['/tests/func/010.phpt']['output']);
 76 | if (isset($array['tests']['/tests/func/010.phpt']['output']) && $strlen >= 165 )
 77 |      echo " OK size:   ".$strlen." - optimal =   167 \n";
 78 | else echo " KO \n";
 79 | 
 80 | printf("%-30s", "phpinfo");
 81 | if (strlen($array['phpinfo']) >= 27940) echo " OK size: ".strlen($array['phpinfo'])." \n";
 82 | else                        echo " KO \n";
 83 | 
 84 | printf("%-30s", "buildEnvironment");
 85 | if (strlen($array['buildEnvironment']) >= 4500)
 86 |      echo " OK size:  ".strlen($array['buildEnvironment'])." \n";
 87 | else echo " KO \n";
 88 | 
 89 | // total diff / output, to see if we parsed everything Ok
 90 | $totalDiff = 0;
 91 | $totalOutput = 0;
 92 | 
 93 | foreach ($array['tests'] as $name => $content) {
 94 |     $totalDiff += strlen($content['diff']);
 95 |     $totalOutput += strlen($content['output']);
 96 | }
 97 | 
 98 | printf("%-30s", "Total diff length");
 99 | if ($totalDiff >= 27900) echo " OK size: ".$totalDiff." - optimal = 27938 \n";
100 | else                     echo " KO \n";
101 | 
102 | printf("%-30s", "Total output length");
103 | if ($totalOutput >= 31950) echo " OK size: ".$totalOutput." - optimal = 31971 \n";
104 | else                       echo " KO \n";
105 | 
106 | 
107 | // now insert data and check
108 | echo "\nTesting SQLite insertion ...\n";
109 | 
110 | $return = insertToDb_phpmaketest($array);
111 | printf("%-30s", "Function call");
112 | 
113 | if ($return === true) echo " OK \n";
114 | else                  echo " KO (return: ".$return.") \n";
115 | 
116 | $dbFile = __DIR__.'/db/'.$array['version'].'.sqlite';
117 | 
118 | printf("%-30s", "DB file exists");
119 | if (file_exists($dbFile)) echo " OK \n";
120 | else                  echo " KO \n";
121 | 
122 | $database = new SQLite3($dbFile, SQLITE3_OPEN_READONLY);
123 | 
124 | if (!$database) {
125 |     die("Error opening DB file: ".$database->lastErrorMsg());
126 | }
127 | 
128 | // Check report ?
129 | $query = 'SELECT * FROM reports WHERE user_email = \'thisisatestmail@testdomain.com\' ORDER BY date DESC LIMIT 1';
130 | $q = $database->query($query);
131 | $sqlReport = $q->fetchArray(SQLITE3_ASSOC);
132 | printf("%-30s", "Found report in DB");
133 | if (is_array($sqlReport) && isset($sqlReport['id']))
134 |      echo " OK (id: ".$sqlReport['id'].") \n";
135 | else echo " KO \n";
136 | 
137 | // check how many failed ?
138 | if (!isset($sqlReport['id'])) die('cannot make more tests');
139 | 
140 | $query = 'SELECT * FROM failed WHERE id_report = '.$sqlReport['id'];
141 | $q = $database->query($query);
142 | $sqlFailed = [];
143 | while ($tab = $q->fetchArray(SQLITE3_ASSOC)) {
144 |     $sqlFailed[$tab['test_name']] = $tab;
145 | }
146 | 
147 | printf("%-30s", "Found 33 failedTest");
148 | if (count($sqlFailed) == 33) {
149 |     echo " OK \n";
150 | } else {
151 |     echo " KO (found: ".count($sqlFailed).") \n";
152 |     var_dump($sqlFailed);
153 | }
154 | 
155 | // expected fail
156 | $query = 'SELECT count(*) FROM expectedfail WHERE id_report = '.$sqlReport['id'];
157 | $q = $database->query($query);
158 | list($nbExpected) = $q->fetchArray();
159 | 
160 | printf("%-30s", "Found 17 expectedFailedTests");
161 | if ($nbExpected == 17) {
162 |     echo " OK \n";
163 | } else {
164 |     echo " KO (found: ".$nbExpected.") \n";
165 | }
166 | 
167 | 
168 | 
169 | printf("%-30s", "specific test diff");
170 | $strlen = strlen($sqlFailed['/tests/func/010.phpt']['diff']);
171 | if (isset($sqlFailed['/tests/func/010.phpt']['diff']) && $strlen >= 290 )
172 |      echo " OK size:   ".$strlen." - optimal =   293 \n";
173 | else echo " KO \n";
174 | 
175 | printf("%-30s", "specific test output");
176 | $strlen = strlen($sqlFailed['/tests/func/010.phpt']['output']);
177 | if (isset($sqlFailed['/tests/func/010.phpt']['output']) && $strlen >= 165 )
178 |      echo " OK size:   ".$strlen." - optimal =   167 \n";
179 | else echo " KO \n";
180 | 
181 | $totalDiff = 0;
182 | $totalOutput = 0;
183 | 
184 | foreach ($sqlFailed as $name => $content) {
185 |     $totalDiff += strlen($content['diff']);
186 |     $totalOutput += strlen($content['output']);
187 | }
188 | 
189 | printf("%-30s", "Total diff length");
190 | if ($totalDiff >= 27900) echo " OK size: ".$totalDiff." - optimal = 27938 \n";
191 | else                     echo " KO \n";
192 | 
193 | printf("%-30s", "Total output length");
194 | if ($totalOutput >= 31950) echo " OK size: ".$totalOutput." - optimal = 31971 \n";
195 | else                       echo " KO \n";
196 | 
197 | // Cleanup
198 | $database->close();
199 | 
200 | $database = new SQLite3($dbFile, SQLITE3_OPEN_READWRITE) or exit('cannot open DB to remove test');
201 | $database->exec('DELETE FROM failed WHERE id_report = '.$sqlReport['id']);
202 | $database->exec('DELETE FROM expectedfail WHERE id_report = '.$sqlReport['id']);
203 | $database->exec('DELETE FROM reports WHERE id = '.$sqlReport['id']);
204 | $database->close();
205 | echo "Cleanup done";
206 | 


--------------------------------------------------------------------------------
/reports/run_tests.php:
--------------------------------------------------------------------------------
  1 |                              |
 16 | #  +----------------------------------------------------------------------+
 17 | 
 18 | $startTime = microtime(true);
 19 | 
 20 | include __DIR__ . '/../include/release-qa.php';
 21 | include __DIR__ . '/../include/functions.php';
 22 | require __DIR__ . '/reportsfunctions.php';
 23 | 
 24 | $CURRENT_PAGE = "Reports";
 25 | common_header();
 26 | echo "\n";
 27 | echo "
\n"; 28 | 29 | $version = $_GET['version'] ?? ''; 30 | if (is_valid_php_version($version, $QA_RELEASES)) { 31 | $tmSiteUpdate = outputTestReportsForVersion($version); 32 | } else { 33 | $tmSiteUpdate = outputTestReportsSummary(); 34 | } 35 | 36 | echo "
\n"; 37 | // Last update = date of last report in this very page 38 | $SITE_UPDATE = date('D M d H:i:s Y T', $tmSiteUpdate)."
". 39 | "Generated in ".round((microtime(true)-$startTime)*1000)." ms"; 40 | common_footer(); 41 | 42 | ///////////////////////////////////////////////////////////////////////////// 43 | 44 | function outputReportTitle(string $TITLE) { 45 | echo '

', 46 | '', 47 | htmlentities($TITLE), "

\n"; 48 | } 49 | 50 | function outputTestReportsSummary() { 51 | outputReportTitle('PHP Test Reports Summary'); 52 | echo << 54 | 55 | 56 | PHP Version 57 | Reports 58 | Unique failed tests 59 | Total failed tests 60 | Last report date 61 | 62 | 63 | 64 | HTML; 65 | 66 | $filter = $_GET['summary_filter'] ?? QA_REPORT_FILTER_ALL; 67 | $reportsPerVersion = get_summary_data($filter); 68 | uksort($reportsPerVersion, 'version_compare'); 69 | $maxReportDate = 0; 70 | foreach ($reportsPerVersion as $version => $line) { 71 | if (version_compare($version, '5.3.8', '<')) { 72 | continue; 73 | } 74 | $tmLastReport = strtotime($line['lastReport']); 75 | if ($maxReportDate < $tmLastReport) $maxReportDate = $tmLastReport; 76 | echo ''; 77 | echo '', 78 | htmlentities($version).''; 79 | echo '', intval($line['nbReports']), ''; 80 | echo '', intval($line['nbFailingTests']), ''; 81 | echo '', intval($line['nbFailures']), ''; 82 | echo "", 83 | format_readable_date($tmLastReport), 84 | ''; 85 | echo "\n"; 86 | } 87 | echo << 89 | 90 |

(Show all versions | 91 | Show stable and current dev only)

92 | HTML; 93 | 94 | return $maxReportDate; 95 | } 96 | 97 | function outputTestReportsForVersion(string $getVersion) { 98 | outputReportTitle("PHP Test Reports For PHP Version $getVersion"); 99 | $isDevVersion = substr($getVersion, -4) === '-dev'; 100 | 101 | $limit = intval($_GET['limit'] ?? 0); 102 | if ($limit <= 0) { 103 | $limit = 50; 104 | } 105 | 106 | $dbFile = __DIR__ . "/db/{$getVersion}.sqlite"; 107 | file_exists($dbFile) or die('no data for this version'); 108 | 109 | $database = new SQLite3($dbFile, SQLITE3_OPEN_READONLY); 110 | ($database instanceof SQLite3) or die("Error opening DB file: ".$database->lastErrorMsg()); 111 | 112 | $failedTestsArray = []; 113 | 114 | // Do we add expected failed ? 115 | if (($_GET['expect'] ?? 0) == 1) { 116 | $query = 'SELECT \'xfail\' as xfail, test_name,COUNT(expectedfail.id) as cpt,\'-\' as variations, 117 | datetime(date) as date FROM expectedfail,reports WHERE expectedfail.id_report = reports.id 118 | GROUP BY test_name ORDER BY cpt DESC LIMIT :limit'; 119 | $stmt = $database->prepare($query); 120 | $stmt->bindValue(':limit', $limit, SQLITE3_INTEGER); 121 | $q = @$stmt->execute(); 122 | if ($q) { 123 | while ($tab = $q->fetchArray(SQLITE3_ASSOC)) { 124 | $failedTestsArray[] = $tab; 125 | } 126 | } 127 | } 128 | 129 | $query = 'SELECT failed.test_name,COUNT(failed.id) as cpt,COUNT(DISTINCT failed.diff) as variations, 130 | datetime(reports.date) as date,success.id as success, r2.id as failedci FROM failed, reports 131 | LEFT JOIN success ON success.test_name=failed.test_name 132 | LEFT JOIN failed f2 ON (f2.test_name=failed.test_name AND f2.output = "") 133 | LEFT JOIN reports r2 ON (f2.id_report = r2.id AND r2.user_email="ciqa") 134 | WHERE failed.id_report = reports.id 135 | GROUP BY failed.test_name ORDER BY cpt DESC LIMIT :limit'; 136 | $stmt = $database->prepare($query); 137 | $stmt->bindValue(':limit', $limit, SQLITE3_INTEGER); 138 | $q = @$stmt->execute(); 139 | $q or die("Error querying DB (error ".$database->lastErrorCode()."): ".$database->lastErrorMsg()); 140 | while ($tab = $q->fetchArray(SQLITE3_ASSOC)) { 141 | $failedTestsArray[] = $tab; 142 | } 143 | $database->close(); 144 | 145 | // Variables interpolated in the following heredoc. 146 | $getVersionURL = urlencode($getVersion); 147 | $expectCHECKED = (($_GET['expect'] ?? 0) == 1) ? ' CHECKED' : ''; 148 | $CIQAcolumn = $isDevVersion ? 'CIQA status' : ''; 149 | echo << 151 | #testList td { 152 | padding: 3px; 153 | } 154 | 155 | 166 | 167 | Show XFAIL
168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | $CIQAcolumn 177 | 178 | 179 | 180 | 181 | HTML; 182 | 183 | $maxReportDate = 0; 184 | foreach ($failedTestsArray as $i => $line) { 185 | $tmDate = strtotime($line['date']); 186 | if ($maxReportDate < $tmDate) $maxReportDate = $tmDate; 187 | 188 | $style = ($i % 2) ? ' style="background-color: #ffcc66"' : ''; 189 | echo " '; 192 | echo ''; 193 | echo ''; 194 | echo "'; 197 | if ($isDevVersion) { 198 | $style = 'background-color: grey'; 199 | $textCI = ' '; 200 | if (!array_key_exists('success', $line)) { 201 | // probably xfail 202 | } elseif ($line['success'] === null) { 203 | // no success. Check fail ? 204 | if (isset($line['failedci'])) { 205 | $style = 'background-color: #c00000'; 206 | $textCI = 'FAIL'; 207 | } 208 | } else { 209 | // success 210 | $style = "background-color: #00c000"; 211 | $textCI = 'PASS'; 212 | } 213 | 214 | echo ""; 215 | } 216 | echo ''; 222 | echo ''."\n"; 223 | } 224 | echo "
Test nameCountVariationsLast report date 
"; 190 | if (isset($line['xfail'])) { echo '[XFAIL] '; } 191 | echo htmlentities($line['test_name']), '', htmlentities($line['cpt']), '', htmlentities($line['variations']), '", 195 | format_readable_date($tmDate), 196 | '$textCI'; 217 | if (!isset($line['xfail'])) { 218 | echo ' 219 | '; 220 | } 221 | echo '
\n"; 225 | 226 | if (count($failedTestsArray) >= $limit) { 227 | echo 'There are more failing tests '; 228 | echo '(view all)'; 229 | } else { 230 | echo 'View only the most common failed tests '; 231 | echo '(view 50)'; 232 | } 233 | 234 | return $maxReportDate; 235 | } 236 | --------------------------------------------------------------------------------