2017-09-27 2 views
15

Ich versuche, Code Testabdeckung für mein PHP-Projekt mit PHPUnit und phpdbg mit dem folgenden Befehl zu generieren:PHPUnit Abdeckung: Erlaubt Speichergröße von 536.870.912 Bytes erschöpft

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

Das funktioniert völlig in Ordnung:

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 

jedoch wenn ich den exakt gleichen Befehl in einem docker Behälter:

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 erhalten folgende Fehlermeldung:

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] 

Ich verstehe nicht, warum PHPUnit 561514763337856 Byte Speicher zuweisen muss. Ich vermute, dass es in einer Schleife stecken bleibt, aber warum passiert das nicht außerhalb des Containers? Hier ist meine PHP-Version auf meinem Rechner:

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 

Und hier ist die .phpunit.cover.xml Datei:

<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 -

ich, dass es gefunden hat etwas mit @runInSeparateProcess zu tun. Wenn ich den Test mit @runInSeparateProcess entferne, beginnt er zu arbeiten. Aber noch weiß ich nicht, was das Problem ist

- EDIT2 -

Auch fand ich heraus, dass, wenn ich nicht bereitgestellt mein Code-Verzeichnis in der alles Docker Behälter funktioniert

+0

Welches Docker-Bild verwenden Sie? ist PHP als Dienst oder als Apache-Modul? Versuchen Sie, den PHP-Speicher in php.ini zu erhöhen. –

+0

Auf welchem ​​OS betreiben Sie das? –

+0

@JoaquinJavi Wie Sie sehen können, ist es ** php: 7.0-Apache **: docker run -it --name YM4UPltmiPMjObaVULwsIPIkPL2bGL0T -e USER = sasan -v "/ home/sasan/Projekt/phpredmin:/phpredmin" -w "/phpredmin "--user" 1000: www-data "** php: 7.0-apache ** phpdbg -dmemory_limit = 512M -qrr ./bin/phpunit -c .phpunit.cover.xml Ich kann nicht meine erhöhen Speicherlimit zu 561514763337856 Bytes –

Antwort

2

Ihr eingehängter Ordner enthält wahrscheinlich alle Hersteller und Cache-Dateien. Versuchen Sie nur den Quellordner zu mounten.

+0

Aber alle phpunit-Dateien und Drittanbieter-Dateien, die in meinen Tests benötigt werden, sind in den Verkäufern. Was bringt es, sie nicht zu montieren? –

+0

können Sie weiterhin auf Anbieter und phpunit zugreifen. Der Datenträger ist eine Art Symlink zu den Dateien, was bedeutet, dass die Änderungen an diesen Dateien auch nach dem Beenden des Containers beibehalten werden. Du kannst es mit diesem 'docker run -it --name YM4UPltmiPMjObaVULwsIPIkPL2bGL0T -e USER = sasan -v"/home/sasan/Projekt/phpredmin/src:/phpredmin/src "-w"/phpredmin "--user" 1000 versuchen : 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

Wenn wir @runInSeparateProcess verwenden, wird PHPUnit versuchen, eingeschlossene Dateien, Ini-Einstellungen, globale Variablen und Konstanten zu serialisieren, um sie an den neuen Prozess zu übergeben. In diesem Fall sah PHPUnit bei der Serialisierung eines dieser Elemente ein rekursives Szenario aus, wodurch der für den PHP-Prozess verfügbare Speicher erschöpft war. Wir müssen ermitteln, was sich zwischen Ihrer lokalen Umgebung und dem Docker-Container geändert hat.

Zunächst können wir versuchen, dieses Serialisierungsverhalten zu deaktivieren, um zu überprüfen, ob wir diesen Pfad verwenden sollten. Fügen Sie die folgenden @preserveGlobalState Anmerkung des Testverfahren, das fehlschlägt:

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

Wenn das das Problem behebt, oder wenn wir einen neuen Fehler zu bekommen, können wir beginnen, für die Unterschiede in den Docker Containern suchen, um das Problem verursachen kann. Ohne mehr Einblick in den Code und Umwelt, ist es schwer zu deuten darauf hin, wo ich anfangen soll, aber hier sind ein paar Ideen:

  • Vergleichen Sie die Ausgabe von php -i aus jeder Umgebung. Achten Sie auf PHP-Erweiterungen, die in einer, aber nicht in der anderen existieren.
  • Verwenden Sie phpdbg, um einen Haltepunkt festzulegen und durch den Code zu gehen. Wir verwenden es bereits, um Coverage zu generieren, aber es ist auch ein nützliches Debugging-Tool. Wir suchen nach dem Element, das die unendliche Rekursion verursacht.Beachten Sie, dass wir den Haltepunkt vor setzen müssen. PHPUnit führt den Testfall wie in der Bootstrap-Datei oder im PHPUnit-Quellcode aus (Zeile 810 von TestCase kann funktionieren).
  • Stellen Sie beim Binden eines Volumes sicher, dass der Benutzer www-data im Container die gleiche UID wie der Benutzer besitzt, der die Dateien auf dem Host besitzt.
  • Versuchen Sie, den Test ohne Speicherbegrenzung auszuführen. Natürlich können wir nicht so viel zuweisen, wie der Fehler vermuten lässt, aber das Speicherlimit kann ein anderes zugrunde liegendes Problem maskieren. Wir können den Container bei Bedarf töten.

Ich konnte dieses Problem nicht reproduzieren einen Dummy-Test in einer ähnlichen Umgebung verwendet (so nah wie ich — gleichen Behälter mit Volumen bekommen konnte), so dass der im Test befindlichen Code des Problems beitragen können.

Verwandte Themen