Growing the PHP core
- one test at a time -

Florian Engelhardt

Husband and dad

First contact with PHP

Nobody will ever use this
— Florian Engelhardt

Who are you?

If I have seen further it is only by standing on the shoulders of giants
— Sir Isaac Newton

Payback time!

Compiling PHP from source

git clone [email protected]:php/php-src.git
cd php-src
./buildconf
./configure
make -j `nproc`

Tests

  • are just .phpt files
  • divided into sections
  • which contain PHP code
  • can run in parallel since 7.4
make TEST_PHP_ARGS=-j`nproc` test

TEST Section

  • simple name for the test
  • longer text goes to DESCRIPTION section
  • mandatory
--TEST--
strlen() function test

SKIPIF Section

  • use case: skip if extension is missing
  • skip if output starts with "skip"
  • expect failure if output starts with "xfail"
  • optional
--SKIPIF--
<?php
if (!extension_loaded('core'))
    die('Skipped: core extension required.');
?>

FILE Section

  • the actual test
  • PHP code enclosed by PHP tags
  • mandatory
--FILE--
<?php
var_dump(strlen('Hello World!'));
?>

EXPECT Section

  • expected output from code in FILE section
  • must match actual output exactly to pass
  • mandatory
--EXPECT--
int(13)

EXPECTF Section

  • alternative to EXPECT
  • substitution tags known from printf() are allowed
--EXPECTF--
int(%d)

XFAIL Section

  • use case: known upstream bugs
  • test is expected to fail
  • why it's expected to fail
  • optional
--XFAIL--
This bug might be still open on aix5.2-ppc64 and hpux11.23-ia64

CLEAN Section

  • use case: clean up after yourself
  • executed after test completes
  • optional
--CLEAN--
<?php
unlink(__DIR__.'/file.tmp');
?>

Basic Test

--TEST--
strlen() function
--SKIPIF--
<?php
if (!extension_loaded('core'))
    die('Skipped: core extension required.');
?>
--FILE--
<?php
var_dump(strlen('Hello World!'));
?>
--EXPECT--
int(13)

What to test?

  • gcov.php.net
  • choose branch (7.1, 7.2, 7.3, 7.4, HEAD)
  • click on coverage

demo

Find something red

ext/zlib/zlib.c in PHP 7.1

Write a test

--TEST--
zlib_get_coding_type() with deflate encoding
--SKIPIF--
<?php if (!extension_loaded("zlib")) print "skip"; ?>
--ENV--
HTTP_ACCEPT_ENCODING=deflate
--FILE--
<?php
ini_set('zlib.output_compression', 'Off');
$encOff = zlib_get_coding_type();
ini_set('zlib.output_compression', 'On');
$encOn = zlib_get_coding_type();
ini_set('zlib.output_compression', 'Off');
var_dump($encOff);
var_dump($encOn);
?>
--EXPECT--
bool(false)
string(7) "deflate"

And make it green

(or blue in this case)

ext/zlib/zlib.c in PHP 7.3

What i learned

  • what looks simple, might be complex
  • there are modify handlers for ini settings
  • HTTP Request is immutable

What do you gain?

🐘

  • phpt test format can be used in PHPUnit
  • PHP will be more stable and reliable
  • deeper understanding of how PHP works internaly

You can call yourself a PHP core contributor!

Furhter readings