attribute php docker phpunit phpdbg

php - attribute - title en css



Cobertura de la unidad PHP: tamaƱo de memoria permitido de 536870912 bytes agotado (3)

Cuando usamos @runInSeparateProcess , PHPUnit intentará serializar los archivos incluidos, las configuraciones ini, las variables globales y las constantes para pasarlas al nuevo proceso. En este caso, parece que PHPUnit encontró un escenario recursivo al serializar uno de estos elementos, lo que agotó la memoria disponible para el proceso de PHP. Necesitamos determinar qué ha cambiado entre su entorno local y el contenedor Docker.

Primero, podemos intentar deshabilitar este comportamiento de serialización para verificar que debemos continuar por este camino. Agregue la siguiente anotación de @preserveGlobalState al método de prueba que falla:

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

Si esto resuelve el problema, o si obtenemos un nuevo error, podemos comenzar a buscar las diferencias en el contenedor de Docker que pueden causar el problema. Sin una mayor visibilidad del código y el entorno, es difícil sugerir dónde comenzar, pero aquí hay algunas ideas:

  • Compara la salida de php -i de cada entorno. Busque las extensiones de PHP que existen en una, pero no la otra.
  • Use phpdbg para establecer un punto de interrupción y recorrer el código. Ya lo estamos usando para generar cobertura, pero también es una herramienta de depuración útil. Estamos buscando el elemento que causa la recursión infinita. Tenga en cuenta que tendremos que establecer el punto de interrupción antes de que PHPUnit ejecute el caso de prueba, como en el archivo de TestCase de TestCase o el código fuente de PHPUnit (la línea 810 de TestCase puede funcionar).
  • Cuando monte un volumen de forma vinculante, asegúrese de que el usuario de www-data en el contenedor tenga el mismo UID que el usuario que posee los archivos en el host.
  • Intente ejecutar la prueba sin la limitación de memoria. Obviamente, no podemos asignar tanto como el error sugiere que podemos necesitar, pero el límite de memoria puede enmascarar otro problema subyacente. Podemos matar el contenedor si es necesario.

No pude reproducir este problema utilizando una prueba ficticia en un entorno similar (lo más cerca que pude conseguir, mismo contenedor con volumen), por lo que el código bajo prueba puede contribuir al problema.

Estoy intentando generar una cobertura de prueba de código para mi proyecto PHP con PHPUnit y phpdbg usando el siguiente comando:

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

Esto funciona perfectamente bien:

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

Sin embargo, cuando uso el mismo comando exacto en un contenedor docker:

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

Obtuve el siguiente error:

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]

No entiendo por qué PHPUnit necesita asignar 561514763337856 bytes de memoria. Sospecho que se atasca en un bucle, pero ¿por qué esto no ocurre fuera del contenedor? Aquí está mi versión de PHP en mi máquina:

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

Y aquí está el archivo .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 -

Descubrí que tiene algo que ver con @runInSeparateProcess. Cuando elimino la prueba que tiene @runInSeparateProcess, entonces comienza a funcionar. Pero todavía no sé cuál es el problema.

- Edit2 -

También descubrí que si no montaba mi directorio de código en el contenedor de Docker, todo funciona bien.


Este es el error de phpdbg. Tenga en cuenta la cantidad de memoria que intenta asignar? Es una locura Me esforcé por averiguar exactamente dónde estaba el error: si el nombre completo del script de prueba (directorio + nombre del archivo de script) excede cierto tamaño, entonces se desborda la pila (sí, ;) y se sobrescribe un entero que especifica la cantidad de memoria que se debe asignar. Luego, el manejo normal de errores entra en juego: no hay suficiente memoria para asignar una cantidad tan insana. Así que esto es para que Krakjoe lo arregle. O puede ser que le haga un parche en mi tiempo libre. Si necesita tener una resolución en este momento: asegúrese de que la ruta del directorio en la que se encuentra su script sea corta.


Su carpeta montada probablemente tiene todos los proveedores y archivos de caché. Intente montar solo la carpeta de origen.