PHPUnit覆盖:允许内存大小536870912字节用尽
我试图用PHPUnit和phpdbg使用下面的命令为我的PHP项目生成代码testing覆盖:
phpdbg -dmemory_limit=512M -qrr ./bin/phpunit -c .phpunit.cover.xml
这工作得很好:
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
但是,当我在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
我得到以下错误:
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]
我不明白为什么PHPUnit需要分配561514763337856字节的内存。 我怀疑它陷入了一个循环,但为什么这不会发生在容器外? 这是我的机器上的PHP版本:
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
这里是.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>
– 编辑1 –
我发现它与@runInSeparateProcess有关。 当我删除具有@runInSeparateProcess的testing时,它开始工作。 但是我仍然不知道是什么问题
– 编辑2 –
另外我发现,如果我不在我的代码目录在Docker容器中安装一切正常
您的挂载文件夹可能包含所有供应商和caching文件。 尝试只安装源文件夹。
当我们使用@runInSeparateProcess
,PHPUnit将尝试序列化包含文件,ini设置,全局variables和常量,以将它们传递给新进程。 在这种情况下,看起来PHPUnit在序列化这些项目之一时遇到了recursion场景,这些项目耗尽了PHP进程可用的内存。 我们需要确定你的本地环境和Docker容器之间的变化。
首先,我们可以尝试禁用这个序列化行为来validation我们应该沿着这条路走下去。 将以下@preserveGlobalState
批注添加到失败的testing方法:
/** * @runInSeparateProcess * @preserveGlobalState disabled */ public function testInSeparateProcess() { // ... }
如果这可以解决问题,或者如果我们得到一个新的错误,我们可以开始寻找可能导致问题的Docker容器的差异。 没有更多的代码和环境的可见性,很难build议从哪里开始,但这里有一些想法:
- 比较来自每个环境的
php -i
的输出。 注意一个存在的PHP扩展,而不是另一个。 - 使用
phpdbg
设置一个断点并逐步执行代码。 我们已经使用它来生成覆盖率,但它也是一个有用的debugging工具。 我们正在寻找导致无限recursion的项目。 请注意,我们需要在 PHPUnit执行testing用例(如引导程序文件或PHPUnit源代码(TestCase
810行可能)) 之前设置断点。 - 绑定卷时,请确保容器中的
www-data
用户具有与拥有主机上文件的用户相同的UID。 - 尝试运行没有内存限制的testing。 显然,我们不能分配尽可能多的错误,但是内存限制可能会掩盖另一个潜在的问题。 如果需要,我们可以杀死容器。
我不能在类似的环境中使用虚拟testing来重现此问题(尽可能地接近容量相同的容器),所以testing中的代码可能会导致问题。
- Docker化的MongoDB在长时间写入capped collectin(SEGFAULT)时不断崩溃,
- 如何克隆和定制laravel homestead并在其中安装更多的东西?
- 缩放Docker容器与孤立的networking
- Tomcat没有在docker映像上运行
- 在Mesos / Marathon上部署端口映射的Docker容器
- Dockerizing Web应用程序(WAR文件)
- 如何指定docker群约束中的经理领导
- Docker和Vagrant连接
- 由于无法启动VM,Docker Quickstart失败:C:\ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe