Running TYPO3 CMS on HHVM (part1)
28.02.2014 HHVM PHP TYPO3

My last try to run TYPO3 CMS on HHVM was few months ago. Then I stumbled upon an issue that PHP constants "PHP_MAXPATHLEN" was not defined. After fixing it I found out that HHVM is not supporting mysqli PHP extension which TYPO3 depends on. So it was impossible to even run unit tests. Implementing this module was not something you can hack overnight, so I left the topic for the future.

Few days ago Facebook announced on the HHVM blog a great news that mysqli finally found its way in to HHVM. 

I took the opportunity to run TYPO3 again. I started with the unit tests to get an impression to what degree TYPO3 is compatible with HHVM.

Short version:

You can run TYPO3 unit tests with HHVM now. However there are many failing tests, and finally there is a fatal error breaking test execution. The first fatal was around 427th test (6%), but after few fixes (incompatible interfaces) I managed to have it run 3294 tests 51% of the whole suite.

Most of the failing tests are related to the usage of Virtual File System (vfs).

I've used  TYPO3 master branch (6.2) and HHVM hightly build  2.5.0-dev+2014.03.02 on Ubuntu 13.10.

Setting up environment

To play with HipHop Virtual Machine I used Ubuntu 13.10 Vagrant box.

Installation of the HHVM

since few months HHVM is also available as nightly build package, so it's really simple to get it on your machine.

I just followed instructions from http://www.hhvm.com/blog/3203/nightly-packages

wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add - 
echo deb http://dl.hhvm.com/ubuntu saucy main | sudo tee /etc/apt/sources.list.d/hhvm.list 
sudo apt-get update sudo apt-get install hhvm-nightly

you can check if installation was successful by running 

hhvm --version

Installation of the TYPO3 CMS

TYPO3 requires imagemagic or graphicsmagic to be installed, so I installed it:

sudo apt-get install imagemagic

In general I followed the build instructions for travis  available in the TYPO3 repository. The TYPO3 CMS Travis project is here.

Checkout TYPO3 CMS sources:

git clone --depth=50 --branch=master git://github.com/TYPO3/TYPO3.CMS.git TYPO3/TYPO3.CMS
cd TYPO3/TYPO3.CMS

Checkout additional tools (helping with setting up db)

git clone --single-branch --branch master --depth 1 git://github.com/typo3-ci/TYPO3-Travis-Integration.git build-environment
source build-environment/install-helper.sh

create some empty folders required by TYPO3

mkdir fileadmin uploads typo3temp

add precooked configuration (it assumes that there is a mysql user named "root" with empty password)

mv build-environment/typo3conf .

clone TYPO3 phpunit extension

git clone --single-branch --branch master --depth 1 git://git.typo3.org/TYPO3CMS/Extensions/phpunit.git typo3conf/ext/phpunit/

Set up database  

mysql -e "DROP DATABASE IF EXISTS typo3_test;" -uroot 
mysql -e "CREATE DATABASE IF NOT EXISTS typo3_test;" -uroot
php build-environment/dbimport/DatabaseImport.php 
mysql -uroot typo3_test < build-environment/dbimport/cli_users.sql 

get phpunit phar 

wget https://phar.phpunit.de/phpunit.phar

Executing tests

To execute unit tests I just run:

hhvm phpunit.phar -c typo3/sysext/core/Build/UnitTests.xml

And the result was:

vagrant@vagrant:~/TYPO3$ hhvm phpunit.phar -c typo3/sysext/core/Build/UnitTests.xml
PHPUnit 3.7.22 by Sebastian Bergmann.

Configuration read from /home/vagrant/www/TYPO3/TYPO3.CMS/typo3/sysext/core/Build/UnitTests.xml

...................................................EEFEEEEEEE   61 / 6347 (  0%)
E.EEFFFFFFFFFFFFFFFFFFFFFFFF............FFFFFFFFFFFFFFFFFFFFF  122 / 6347 (  1%)
FFFEEEEEE.EESSSSSSSSSSSSSS...............SSSSSSSSSSSSSSSSSSSS  183 / 6347 (  2%)
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS........................  244 / 6347 (  3%)
................SSSSSSSSSSSSSSSSSSSSSSSSSS...................  305 / 6347 (  4%)
......................S...S....S.............................  366 / 6347 (  5%)
..............................FFFFF......FFFF................  427 / 6347 (  6%)
.......HipHop Fatal error: Declaration of Mock_PackageManager_f139390c::initialize() must be compatible 
with that of TYPO3\Flow\Package\PackageManagerInterface::initialize() in 
/home/vagrant/www/TYPO3/TYPO3.CMS/typo3conf/ext/phpunit/Composer/vendor/phpunit/phpunit-mock-objects/PHPUnit/Framework/MockObject/Generator.php(231) 
: eval()'d code on line 1
Core dumped: Segmentation fault
Segmentation fault (core dumped)

There are many test errors and failures and at the end we've got a fatal error. The fatal was thrown because the initialize() method from PackageManager was not compatible with the one from PackagaManagerInterface.

As a quick workaround I removed initialize method declaration from the interface. I've also reported this issue on the TYPO3 Flow bugtracker http://forge.typo3.org/issues/56409 

BTW, the segmentation fault error you can see at the end of the listing is not caused by phpunit, but a bug with HHVM (even hhvm --version results in the segfault). I reported it here.

After running the test suite again I've got similar issue with the boot() method from Package, and PackageInterface. After fixing it, I run the tests again:

vagrant@vagrant:~/TYPO3$ hhvm phpunit.phar -c typo3/sysext/core/Build/UnitTests.xml
PHPUnit 3.7.22 by Sebastian Bergmann.

Configuration read from /home/vagrant/www/TYPO3/typo3/sysext/core/Build/UnitTests.xml

...................................................EEFEEEEEEE   61 / 6347 (  0%)
E.EEFFFFFFFFFFFFFFFFFFFFFFFF............FFFFFFFFFFFFFFFFFFFFF  122 / 6347 (  1%)
FFFEEEEEE.EESSSSSSSSSSSSSS...............SSSSSSSSSSSSSSSSSSSS  183 / 6347 (  2%)
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS........................  244 / 6347 (  3%)
................SSSSSSSSSSSSSSSSSSSSSSSSSS...................  305 / 6347 (  4%)
......................S...S....S.............................  366 / 6347 (  5%)
..............................FFFFF......FFFF................  427 / 6347 (  6%)
.......EEEEEEE...............................................  488 / 6347 (  7%)
.....E.......................................................  549 / 6347 (  8%)
.............................................................  610 / 6347 (  9%)
.............................................................  671 / 6347 ( 10%)
.............................................................  732 / 6347 ( 11%)
.............................................................  793 / 6347 ( 12%)
.............................................................  854 / 6347 ( 13%)
.............................................................  915 / 6347 ( 14%)
...........EE..F......................................E....EF  976 / 6347 ( 15%)
EEEEE.FEEF.FE.....EEEEE...E...EEEEE.......................... 1037 / 6347 ( 16%)
..................EEEEEEEEEEEEFEEEEEEEE.EFEEEFEEEEEEFEFEEE... 1098 / 6347 ( 17%)
.EEEEEEEEEEEEEFEEEFEEEEEEE........S...........SSSSSSS........ 1159 / 6347 ( 18%)
...............................EEEEE...............E...E.E... 1220 / 6347 ( 19%)
............................................................. 1281 / 6347 ( 20%)
......................F...................................... 1342 / 6347 ( 21%)
..........................................FFF................ 1403 / 6347 ( 22%)
............................................................. 1464 / 6347 ( 23%)
............................................................. 1525 / 6347 ( 24%)
............................................................. 1586 / 6347 ( 24%)
............................................................. 1647 / 6347 ( 25%)
............................................................. 1708 / 6347 ( 26%)
............................................................. 1769 / 6347 ( 27%)
............................................................. 1830 / 6347 ( 28%)
............................................................. 1891 / 6347 ( 29%)
........................................F.................... 1952 / 6347 ( 30%)
............................................................. 2013 / 6347 ( 31%)
.......S.....SSSF.............FFFFFFFEF...................... 2074 / 6347 ( 32%)
............................................................. 2135 / 6347 ( 33%)
............................................................. 2196 / 6347 ( 34%)
...........................................F................. 2257 / 6347 ( 35%)
............................................................. 2318 / 6347 ( 36%)
.................................................F........... 2379 / 6347 ( 37%)
............................................................. 2440 / 6347 ( 38%)
...............S............................................. 2501 / 6347 ( 39%)
.................EEEEEEEEEEEE................................ 2562 / 6347 ( 40%)
............................................................. 2623 / 6347 ( 41%)
............................................................. 2684 / 6347 ( 42%)
......................................S...EEEE............... 2745 / 6347 ( 43%)
............................................................. 2806 / 6347 ( 44%)
............................................................. 2867 / 6347 ( 45%)
............................................................. 2928 / 6347 ( 46%)
............................................................. 2989 / 6347 ( 47%)
...E......................................................... 3050 / 6347 ( 48%)
..........................E.EEEEE.EEEE.EEEEE.EEEEE.EEEEEEE.EE 3111 / 6347 ( 49%)
EEE.EEEEEEE.EEE.............................E................ 3172 / 6347 ( 49%)
............................................................. 3233 / 6347 ( 50%)
.....................E...E................................... 3294 / 6347 ( 51%)
................Core dumped: Segmentation fault
Segmentation fault (core dumped)

Much better now, but for some reason hhvm crashes after executing half of the test suit. I will investigate it later, now let's take a look at some filing tests.

Most of the failing tests are related to usage of Virtual File System, for example:

1) TYPO3\CMS\Core\Tests\Unit\Cache\Backend\FileBackendTest::getCacheDirectoryReturnsTheCurrentCacheDirectory TYPO3\CMS\Core\Cache\Exception: The directory "vfs://Foo/Cache/Data/SomeCache/" is not writable. /home/vagrant/www/TYPO3/TYPO3.CMS/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php:200 /home/vagrant/www/TYPO3/TYPO3.CMS/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php:101 /home/vagrant/www/TYPO3/TYPO3.CMS/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php:121 /home/vagrant/www/TYPO3/TYPO3.CMS/typo3/sysext/core/Tests/Unit/Cache/Backend/FileBackendTest.php:76 phar://phpunit-3.7.32.phar/phpunit/TextUI/Command.php:176 phar://phpunit-3.7.32.phar/phpunit/TextUI/Command.php:129 /home/vagrant/www/TYPO3/TYPO3.CMS/phpunit.phar:615

So I've installed the vfsStream library and tried to run it's unit tests on hhvm:

Unfortunatelly they are red...

Tests: 328, Assertions: 1135, Failures: 27, Errors: 15, Skipped: 14.

I've created an issue for it on HipHop bugtracker with instructions how to run vfsStream tests.

EDIT: I've created a pull request to HHVM to include vfsStream unit tests in their framework parity check and it was merged. Now you can watch vfsStream compatibility on http://www.hhvm.com/frameworks/ 

That's it for part 1. In the next articles I want to cover following action points:

  • why HipHop stops execution at some point instead of running the whole suite
  • check why vfs tests are failing
  • check other tests (no vfs related), how we can improve compatibility with HHVM (or how to fix HHVM itself)
  • ask HipHop team to include TYPO3 test suite in their build process