Nette\Tester: vyřešený problém s prostředím a nápady na vylepšení
- Eda
- Backer | 220
Zdarec.
Přišel jsem po čase k projektu, kde mám pár testů a chtěl jsem pokračovat ve vývoji. První, co jsem chtěl udělat, bylo spustit stávající testy. Nedávno jsem totiž u sebe migroval na PHP7, tak jsem předpokládal, že se možná něco rozbilo.
Zavolal jsem tedy příkaz pro tester se změněným php.ini:
vendor/bin/tester ./tests -p php -c /etc/php/7.0/apache2/php.ini
A opravdu, něco se pokazilo :-) Dostávám:
-- FAILED: evidencia-dopravcov/tests/DataLogEntityPreparer.phpt
Exited with error code 254 (expected 0)
-- FAILED: evidencia-dopravcov/tests/UserOldRolesFixer.phpt
Exited with error code 254 (expected 0)
Tady bylo trochu WTF. Když si přímo v souborech s testy něco dumpuju,
ve výstupu konzole se to neobjeví, ani když přidám přepínač
--debug
. Žádný jiný přepínač pro „zachování výstupu“
jsem nenašel. Nešlo by tohle nějak upravit? Nebo to jde a špatně jsem
hledal?
Nakonec jsem postupným laděním zjistil, že to padá v konstruktoru
RobotLoader
u:
public function __construct()
{
if (!extension_loaded('tokenizer')) {
throw new Nette\NotSupportedException('PHP extension Tokenizer is not loaded.');
}
}
Další WTF. Proč mi Tester neukázal přímo tu Exceptionu a místo, kde to spadlo? To by mi ušetřilo dost času při ručním hledání.
Po tomto zjištění si říkám, jasně, nemám nalinkované nějaké rozšíření, nalinkuju ho a pohoda.
Ale v PHP manuálu píšou, že Tokenizer je již od nějaké pradávné verze přímo součástí PHPka.
Divné. Zkusím to tedy ověřit. Do konzole zadám:
php -m | grep tokenizer
-- nebo
php -r "var_dump( get_loaded_extensions() );"
A opravdu tokenizer k dispozici i v command-line je.
Zkouším jeden test pustit jako spustitelný skript jen pomocí phpka:
php tests/DataLogEntityPreparer.phpt
Skript skončí bez chyb. Pro jistotu zkouším explicitně uvést název php.ini souboru:
php tests/DataLogEntityPreparer.phpt -c /etc/php/7.0/apache2/php.ini
Opět bez chyb.
Dokonce, když dumpnu hned na začátku tester.php informaci o tom, zda je tokenizer načten:
var_dump(extension_loaded('tokenizer'));
Tak zjistím, že ano (true).
Když ale stejnou funkci zavolám až v samotném testu, skončí to false.
Tester tedy spouští PHP proces pro testy nějak „špatně“. Když si vypíšu informace o běhovém prostředí pro Tester, dostanu tohle:
$ vendor/bin/tester -i -p php -c /etc/php/7.0/apache2/php.ini
_____ ___ ___ _____ ___ ___
|_ _/ __)( __/_ _/ __)| _ )
|_| \___ /___) |_| \___ |_|_\ v1.7.1
PHP binary:
/usr/bin/php7.0
PHP version:
7.0.7-4+deb.sury.org~trusty+1 (cli)
Loaded php.ini files:
/etc/php/7.0/apache2/php.ini
Loaded extensions:
Core, date, filter, hash, libxml, openssl, pcntl, pcre, Reflection, session, SPL, standard, zlib
Binárka je stejná, php.ini je stejné… co se tedy liší v testeru oproti normálnímu spuštění PHPka v konzoli, že jednou tam tokenizer je a podruhé není?
Nic, situaci teda vyřeším tak, že „extension=tokenizer.so“ přidám přímo do php.ini, který linkuju, případně parametrem „-d“ pro Tester.
Ale dalo to zabrat, než jsem se k tomu dostal.
Třeba někdo bude řešit něco podobného a tento post mu pomůže.
A třeba se někdo ( @Milo ? ) vyjádří k těm dvěma WTF, na které jsem narazil, a třeba se díky tomu povede Tester zase posunout dál :-)
Edit: A příběh pokračuje. Těch rozšíření chybí při spuštění testeru mnohem víc. Takže jsem všechny ručně musel přidat do php.ini. Při ručním spuštění se nahrají automaticky všechna rozšíření ze složky /etc/php/7.0/apache2/conf.d, při spuštění Testerem ne.
Když zkontroluju výstup php_ini_scanned_files(), dostanu tohle:
$php -r "var_dump(php_ini_scanned_files());"
string(1207) "/etc/php/7.0/cli/conf.d/10-mysqlnd.ini,
/etc/php/7.0/cli/conf.d/10-opcache.ini,
/etc/php/7.0/cli/conf.d/10-pdo.ini,
/etc/php/7.0/cli/conf.d/15-xml.ini,
/etc/php/7.0/cli/conf.d/20-calendar.ini,
/etc/php/7.0/cli/conf.d/20-ctype.ini,
/etc/php/7.0/cli/conf.d/20-curl.ini,
/etc/php/7.0/cli/conf.d/20-dom.ini,
/etc/php/7.0/cli/conf.d/20-exif.ini,
/etc/php/7.0/cli/conf.d/20-fileinfo.ini,
/etc/php/7.0/cli/conf.d/20-ftp.ini,
/etc/php/7.0/cli/conf.d/20-gettext.ini,
/etc/php/7.0/cli/conf.d/20-iconv.ini,
/etc/php/7.0/cli/conf.d/20-json.ini,
/etc/php/7.0/cli/conf.d/20-mcrypt.ini,
/etc/php/7.0/cli/conf.d/20-mysqli.ini,
/etc/php/7.0/cli/conf.d/20-pdo_mysql.ini,
/etc/php/7.0/cli/conf.d/20-phar.ini,
/etc/php/7.0/cli/conf.d/20-posix.ini,
/etc/php/7.0/cli/conf.d/20-readline.ini,
/etc/php/7.0/cli/conf.d/20-shmop.ini,
/etc/php/7.0/cli/conf.d/20-simplexml.ini,
/etc/php/7.0/cli/conf.d/20-sockets.ini,
/etc/php/7.0/cli/conf.d/20-sysvmsg.ini,
/etc/php/7.0/cli/conf.d/20-sysvsem.ini,
/etc/php/7.0/cli/conf.d/20-sysvshm.ini,
/etc/php/7.0/cli/conf.d/20-tokenizer.ini,
/etc/php/7.0/cli/conf.d/20-wddx.ini,
/etc/php/7.0/cli/conf.d/20-xmlreader.ini,
/etc/php/7.0/cli/conf.d/20-xmlwriter.ini,
/etc/php/7.0/cli/conf.d/20-xsl.ini
Při volání php z testeru ale scanned files úplně chybí – tzn. načítá se jen ten ini file, který se předá v konfiguraci, ini fily pro ta rozšíření už ne.
Bohužel, runtimově zřejmě nejde konfigurace
--with-config-file-scan-dir
při volání php nijak přenastavit…
Takže jdu cestou vlastního ini konfigu pro testy, který bude obsahovat
původní konfig + všechny konfigy rozšíření.
Editoval Eda (17. 6. 2016 21:26)
- Milo
- Nette Core | 1283
Když si přímo v souborech s testy něco dumpuju, ve výstupu konzole se to neobjeví.
Teď to jednoduše nejde. Ale když test failuje, stdout se vypíše.
V hlavě mám na to TODO, ale hned tak to nebude. --debug
je
v podstatě internal a k tomuhle neslouží.
Další WTF. Proč mi Tester neukázal přímo tu Exceptionu a místo, kde to spadlo?
Voláš v boostrapu testů Environment::setup()
?
Potíž s --with-config-file-scan-dir
se objevuje často. Je to
zmíněno
v dokumentaci. Issues k tomu bylo hodně, v Testeru 2.x bude existovat
berlička, řeší se to v #290. IMHO, testy by měly
být distribuovány s vlastním php.ini
, aby bylo zřejmé, jaké
rozšíření pro svůj běh potřebují.
- Šaman
- Člen | 2659
Dumpování v testech jsem vyřešil takhle, jen je potřeba spustit si konkrétní test v prohlížeči. To dělám vždy, když je píšu, spouštění z IDE/konzole provádím jen když provedu nějaké úpravy kódu aplikace a chci si ověřit, že se nic nerozbilo.
Co se php.ini
týče, tak to řeším stejně, jako config. Tj.
v repozitáři mám php.sample.ini
ve kterém je seznam všech
nutných nastavení a modů a v .gitignore ignoruji php.ini
, který
bude závislý na konkrétním stroji (adresy knihoven rozšíření na
disku apod.)
Editoval Šaman (19. 6. 2016 22:34)