sebastianbergmann/phpunit — Issue #419: Out of memory when assertNull() or assertSame() fail and $actual is a really, really big object.
Author: todofixthis
Created: 2011-11-25 18:15:45+00:00
State: open

Consider the following test in a Symfony 1.4 / Doctrine 1.2 project:

public function testCannotResolveByPK( )
{
/** @var $record MyModel */
$record = $this->getFixtureVar('MyModelTestFixture');

$this->assertNull(MyModelTable::getInstance()->resolve($record->getId(), true),
'Expected PK value to be unresolvable (due to conflict with some_other_id).'
);
}

This test fails catastrophically:

PHPUnit 3.6.4 by Sebastian Bergmann.

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 115343361 bytes) in /usr/share/pear/PHPUnit/Util/Type.php on line 161

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 115343361 bytes) in /usr/share/pear/PHPUnit/Util/Type.php on line 161

I get the same result if I try `$this->assertSame(null, ...`.

However, if I change the assertion to `assertEquals()`, I get a much more manageable failure:

PHPUnit 3.6.4 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 18.50Mb

There was 1 failure:

1) MyModelTableTest::testCannotResolveByPK
Expected PK value to be unresolvable (due to conflict with some_other_id).
MyModel Object (...) does not match expected type "NULL".

Note that `MyModelTable->resolve()` returns a `Doctrine_Record`. These instances are **huge**, containing references to other similarly large objects. My guess is that PHP is running out of memory when it tries to capture the output from `print_r()` (see https://github.com/sebastianbergmann/phpunit/blob/3.6.4/PHPUnit/Util/Type.php#L161).

This ticket might be related to #119 and #296.

---

A proof-of-concept can be reproduced using the following test:

public function testSomethingShouldBeNull( )
{
$this->assertNull((object) range(1, 100));
}

The output of this test is as follows:

PHPUnit 3.6.4 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 17.25Mb

There was 1 failure:

1) SampleTest::testSomethingShouldBeNull
Failed asserting that stdClass Object (
0 => 1
1 => 2
2 => 3
3 => 4
4 => 5
5 => 6
...
95 => 96
96 => 97
97 => 98
98 => 99
99 => 100
) is null.

Similar behavior occurs when changing `assertNull()` to `assertSame()`.

Now see what happens when I change `assertNull()` to `assertEquals()`:

public function testSomethingShouldBeNull( )
{
$this->assertEquals(null, (object) range(1, 100));
}

PHPUnit 3.6.4 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 17.25Mb

There was 1 failure:

1) SampleTest::testSomethingShouldBeNull
stdClass Object (...) does not match expected type "NULL".