2017-09-27 59 views
15

Próbuję wygenerować kod pokrycia testowego dla mojego projektu PHP z PHPUnit i phpdbg za pomocą następującego polecenia:PHPUnit zasięg: Dozwolony rozmiar pamięci 536870912 bajtów wyczerpane

phpdbg -dmemory_limit=512M -qrr ./bin/phpunit -c .phpunit.cover.xml 

to działa perfekcyjnie:

PHPUnit 6.2.4 by Sebastian Bergmann and contributors. 

........               8/8 (100%) 

Time: 114 ms, Memory: 14.00MB 

OK (8 tests, 13 assertions) 

Generating code coverage report in HTML format ... done 

jednak kiedy używam dokładnie to samo polecenie w pojemniku Döcker:

docker run -it --name YM4UPltmiPMjObaVULwsIPIkPL2bGL0T -e USER=sasan -v "/home/sasan/Project/phpredmin:/phpredmin" -w "/phpredmin" --user "1000:www-data" php:7.0-apache phpdbg -dmemory_limit=512M -qrr ./bin/phpunit -c .phpunit.cover.xml 

I Pojawia się następujący błąd:

PHPUnit 6.2.4 by Sebastian Bergmann and contributors. 

[PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 561514763337856 bytes) in /phpredmin/vendor/phpunit/phpunit/src/Util/GlobalState.php on line 166] 

ja nie rozumiem, dlaczego PHPUnit musi przeznaczyć 561514763337856 bajtów pamięci. Podejrzewam, że utknie w pętli, ale dlaczego tak się nie dzieje poza kontenerem? Oto moja wersja PHP na moim komputerze:

PHP 7.0.22-0ubuntu0.17.04.1 (cli) (built: Aug 8 2017 22:03:30) (NTS) 
Copyright (c) 1997-2017 The PHP Group 
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies 
    with Zend OPcache v7.0.22-0ubuntu0.17.04.1, Copyright (c) 1999-2017, by Zend Technologies 

i tutaj jest plik .phpunit.cover.xml:

<phpunit 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd" 
     backupGlobals="false" 
     backupStaticAttributes="false" 
     bootstrap="vendor/autoload.php" 
     cacheTokens="false" 
     colors="false" 
     convertErrorsToExceptions="true" 
     convertNoticesToExceptions="true" 
     convertWarningsToExceptions="true" 
     processIsolation="false" 
     stopOnError="true" 
     stopOnFailure="true" 
     stopOnIncomplete="false" 
     stopOnSkipped="false" 
     stopOnRisky="false" 
     timeoutForSmallTests="1" 
     timeoutForMediumTests="10" 
     timeoutForLargeTests="60" 
     verbose="false"> 
    <testsuites> 
      <testsuite name="PhpRedmin PHP source"> 
      <directory>src-test/</directory> 
      </testsuite> 
    </testsuites> 
    <logging> 
     <log type="coverage-html" target="cover/" lowUpperBound="35" 
highLowerBound="70"/> 
    </logging> 
    <filter> 
     <whitelist processUncoveredFilesFromWhitelist="true"> 
      <directory suffix=".php">src-test/</directory> 
      <directory suffix=".php">src/</directory> 
     </whitelist> 
    </filter> 
</phpunit> 

- Edit1 -

Okazało się, że to ma coś wspólnego z @runInSeparateProcess. Po usunięciu testu z @runInSeparateProcess zaczyna działać. Ale nadal nie wiem co jest problemem

- Edit2 -

Ponadto okazało się, że Jeśli nie montować moje katalogu kodu w kontenerze Docker wszystko działa poprawnie

+0

Jakiego obrazu dokowanego używasz? jest php jako usługa lub jako moduł apache? , spróbuj zwiększyć pamięć php w php.ini –

+0

Na jakim systemie operacyjnym to działasz? –

+0

@JoaquinJavi Jak widać **: php: 7.0-apache **: uruchamianie dockera -it --name YM4UPltmiPMjObaVULwsIPIkPL2bGL0T -e USER = sasan -v "/ home/sasan/Project/phpredmin:/phpredmin" -w "/phpredmin "--user" 1000: www-data "** php: 7.0-apache ** phpdbg -dmemory_limit = 512M -qrr ./bin/phpunit -c .phpunit.cover.xml Nie mogę zwiększyć mojego Limit pamięci do 561514763337856 bajtów –

Odpowiedz

2

Zainstalowany folder prawdopodobnie zawiera wszystkich dostawców i pliki pamięci podręcznej. Spróbuj zamontować tylko folder źródłowy.

+0

Jednak wszystkie pliki phpunit i pliki trzeciej strony potrzebne w moich testach są u dostawców. Po co ich nie montować? –

+0

nadal można uzyskać dostęp do dostawców i phpunit. Wolumin jest swego rodzaju dowiązaniem symbolicznym do plików, co oznacza, że ​​zmiany w tych plikach będą zachowane nawet po zatrzymaniu kontenera. możesz go wypróbować tym '' docker run -it --name YM4UPltmiPMjObaVULwsIPIkPL2bGL0T -e USER = sasan -v "/ home/sasan/Project/phpredmin/src:/phpredmin/src" -w "/ phpredmin" --user "1000 : www-data "php: 7.0-apache phpdbg -dmemory_limit = 512M -qrr ./bin/phpunit -c .phpunit.cover.xml ' https://docs.docker.com/glossary/?term=volume – Asha

2

Kiedy używamy @runInSeparateProcess, PHPUnit podejmie próbę uszeregowania zawartych plików, ustawień ini, zmiennych globalnych i stałych w celu przekazania ich do nowego procesu. W tym przypadku wygląda na to, że PHPUnit napotkało rekurencyjny scenariusz podczas serializacji jednego z tych elementów, które wyczerpały pamięć dostępną dla procesu PHP. Musimy określić, co zmieniło się pomiędzy lokalnym środowiskiem a kontenerem Docker.

Po pierwsze możemy spróbować wyłączyć to zachowanie serializacji, aby sprawdzić, czy powinniśmy postępować zgodnie z tą ścieżką Dodaj następujący @preserveGlobalState adnotacji do metody badawczej, która zawodzi:

/** 
* @runInSeparateProcess 
* @preserveGlobalState disabled 
*/ 
public function testInSeparateProcess() 
{ 
    // ... 
} 

Jeżeli to rozwiąże problem, czy możemy dostać nowy błąd, możemy zacząć patrząc na różnice w pojemniku Docker, które mogą powodować problem. Bez większej widoczności w kodzie i środowiska, trudno się sugerować, od czego zacząć, ale oto kilka pomysłów:

  • porównać wyjście php -i z każdego środowiska. Uważaj na rozszerzenia PHP istniejące w jednym, ale nie na drugim.
  • Użyj phpdbg, aby ustawić punkt przerwania i przejść przez kod. Używamy go już do generowania pokrycia, ale jest to również przydatne narzędzie do debugowania. Szukamy przedmiotu, który powoduje nieskończoną rekursję.Zauważ, że będziemy musieli ustawić punkt przerwania przed PHPUnit wykona test case, taki jak w pliku bootstrap lub w kodzie źródłowym PHPUnit (linia 810 z TestCase może działać).
  • Podczas łączenia woluminu z woluminem upewnij się, że użytkownik www-data w kontenerze ma ten sam identyfikator UID, co użytkownik, który jest właścicielem plików na hoście.
  • Spróbuj wykonać test bez ograniczenia pamięci. Oczywiście nie możemy przydzielić tak dużo, jak sugeruje błąd, ale może to oznaczać, że limit pamięci może maskować inny podstawowy problem. W razie potrzeby możemy zabić kontener.

nie mogę odtworzyć ten problem przy użyciu manekina w podobnym środowisku (tak blisko, jak mogę dostać — sam pojemnik z tomu), więc kod badany może przyczynić się do problemu.