Slide 1

Slide 1 text

test||die Testing the PHP implementation Zoë Slattery PHP London , February 29th 2008

Slide 2

Slide 2 text

PHP Interpreter Extensions ( C ) PHP code Why is the initialisation of class values unpredictable? Enough! – I’m going to spend my free time at parties…no more PHP Another BOGUS bug! I want to check­in this elegant bug fix but I have no clue what else it might break… Why is ­2^31 a float sometimes and an int other times? WHY?

Slide 3

Slide 3 text

int(2147483647) int(­2147483648) float(­2147483648) EXAMPLE 1

Slide 4

Slide 4 text

B A K class C { const A = K; const B = K; } class C { public static $a = K; public static $b = K; } $b $a K C::A; K B A K K K C::$a; $b $a K echo “C::A = “.C::A.”\n”; echo “C::B = “.C::B.”\n”; 6 6 K B A K K K 6 echo “C::$a = “.C::$a.”\n”; echo “C::$b = “.C::$b.”\n”; $b $a K define(‘K’, 6); K 6 B A K define(‘K’, 6); K K 6 $b $a K Class constants Static variables EXAMPLE 2

Slide 5

Slide 5 text

Changes in source/ext, source/Zend, source/tests This looks like a lot …but actually – it’s a drop in the ocean …. What are we doing? 2005 2006 2007 2008 0 500 1000 1500 2000 2500 C and PHPT files changed in PHP 5 C files added C files modified PHPT files added PHPT files modified Year Number of files

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

A simple PHPTest ­­TEST­­ strtr() function ­ basic test for strtr() ­­FILE­­ "hi", "hi"=>"hello", "a"=>"A", "world"=>"planet"); var_dump(strtr("# hi all, I said hello world! #", $trans)); ?> ­­EXPECT­­ string(32) "# hello All, I sAid hi planet! #"

Slide 9

Slide 9 text

test.phpt test.out test.exp test.diff run­tests.php Summary Summary + files Running PHPT tests php run­tests.php test.phpt Pass Fail

Slide 10

Slide 10 text

PHP needs TESTS! PHP doesn't have enough test cases If you can write PHP you can write tests Writing tests can help improve your PHP coding Marcus BÖrger's slides on writing tests http://talks.somabo.de/

Slide 11

Slide 11 text

Get involved!

Slide 12

Slide 12 text

PHP Worldwide http://wiki.pooteeweet.org/TestFest LONDON! Second week in May – watch this Wiki!

Slide 13

Slide 13 text

Slide 14

Slide 14 text

EXAMPLE 3 Functions which expect integer input cast floating point values to int. #define DVAL_TO_LVAL(d, l) \ if ((d) > LONG_MAX) { \ (l) = (unsigned long) (d); \ } else { \ (l) = (long) (d); \ } Linux, Windows 32 => lowest 32 bits of the representation as an integer. Mac=> lowest 32 bit UNLESS the integer overflows THEN ­1. Functions which are passed doubles by mistake will give unpredictable results on all platforms unless the function code makes an explicit check.

Slide 15

Slide 15 text

This went into PHP4: #define DVAL_TO_LVAL(d, l) \ if ((d) > LONG_MAX) { \ (l) = LONG_MAX; \ } else if ((d) < LONG_MIN) {/ (l) = LONG_MIN; \ } else { \ (l) = (long) (d); \ } Didn't work – Bug 30695 Will convert 0x80000000 to INT_MAX (0x7FFFFFFF). What now? special case 0x8000000 to 0xFFFFFFFF (what side effects would there be?) every extension does it’s own checking (time consuming!) EXAMPLE 3 ­ Fix#1

Slide 16

Slide 16 text

Integer repr'n in decimal on Mac Integer rep'n in decimal on Linux/Win Integer represented in hex on Lin/Win Cast to integer Floating point representation of 4 bits O’flow ­1 1 0x1 0001 0001 INT_MAX * 2 + 3 (17) ­1 0 0x0 0000 0001 INT_MAX *2 + 2 (16) ­1 ­1 0xF 1111 INT_MAX *2 + 1 (15) ­2 ­2 0xE 1110 INT_MAX *2 (14) ­3 ­3 0xD 1101 INT_Max * 2 – 1 (13) ­7 ­7 0x9 1001 INT_MAX + 2 (9) ­8 ­8 0x8 1000 INT_MAX + 1 (8) 7 7 0x7 0111 INT_MAX (7) EXAMPLE 3 ­ details

Slide 17

Slide 17 text

EXAMPLE 3 ­ Fix#2 # define DVAL_TO_LVAL(d, l) \ if ((d) > LONG_MAX) { \ if ((d) > MAX_UNSIGNED_INT) { \ (l) = LONG_MAX; \ } else { \ (l) = (unsigned long) (d); \ } \ } else { \ if((d) < LONG_MIN) { \ (l) = LONG_MIN; \ } else { \ (l) = (long) (d); \ } \ }