Skip to content
This repository

ErrorException: Notice: ob_end_clean(): failed to delete buffer. #390

Closed
sebastianblum opened this Issue November 01, 2011 · 24 comments
Sebastian Blum

Hello!

I'am using symfony 2.0.4 and the example was working with phpunit 3.5.15.

Since the upgrade to phpunit 3.6 i get the following output:

phpunit -c app
#!/usr/local/Cellar/php/5.3.6/bin/php
PHPUnit 3.6.0 by Sebastian Bergmann.

Configuration read from /Users/sebiprivat/Downloads/Symfony/app/phpunit.xml.dist

.E

Time: 1 second, Memory: 25.50Mb

There was 1 error:

1) Acme\DemoBundle\Tests\Controller\DemoControllerTest::testInvalidName
ErrorException: Notice: ob_end_clean(): failed to delete buffer. No buffer to delete in /usr/local/Cellar/php/5.3.6/lib/php/PHPUnit/Framework/TestCase.php line 833

/Users/sebiprivat/Downloads/Symfony/vendor/symfony/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php:65
/usr/local/Cellar/php/5.3.6/bin/phpunit:46

FAILURES!
Tests: 2, Assertions: 2, Errors: 1.
MacPro:Symfony sebiprivat$


Steps to reproduce the error:

  1. Download Symfony v2.0.4 with vendors
    http://symfony.com/download?v=Symfony_Standard_Vendors_2.0.4.tgz

  2. Go into the directory and run phpunit -c app
    There should be one test in the Acme Demo Bundle

  3. Now I want to test, that symphony throws a NotFoundException (will display a 404 error page) if no name was given

I edited in src/Acme/DemoBundle/Controller/DemoController.php to

public function helloAction($name)
{
if (!$name) {
throw new NotFoundHttpException("No Name!");
}
return array('name' => $name);
}

and added a new test in src/Acme/DemoBundle/Tests/Controller/DemoControllerTest.php

public function testInvalidName()
{
$client = $this->createClient();
$crawler = $client->request('GET', '/demo/hello/');
$this->assertTrue($client->getResponse()->isNotFound());
}

Now running phpunit -c app will get the following output:

phpunit -c app
#!/usr/local/Cellar/php/5.3.6/bin/php
PHPUnit 3.6.0 by Sebastian Bergmann.

Configuration read from /Users/sebiprivat/Downloads/Symfony/app/phpunit.xml.dist

.E

Time: 1 second, Memory: 25.50Mb

There was 1 error:

1) Acme\DemoBundle\Tests\Controller\DemoControllerTest::testInvalidName
ErrorException: Notice: ob_end_clean(): failed to delete buffer. No buffer to delete in /usr/local/Cellar/php/5.3.6/lib/php/PHPUnit/Framework/TestCase.php line 833

/Users/sebiprivat/Downloads/Symfony/vendor/symfony/src/Symfony/Component/HttpKernel/Debug/ErrorHandler.php:65
/usr/local/Cellar/php/5.3.6/bin/phpunit:46

FAILURES!
Tests: 2, Assertions: 2, Errors: 1.
MacPro:Symfony sebiprivat$

Sebastian Bergmann

Are you (or Symfony 2) using Output Buffering in some way?

Markus Bachmann

The PhpEngine and Twig use output buffering.

Sebastian Blum

Yes, symfony and twig are using Output Buffering

I don't know how symfony generates the 404 page from the NotFoundException.
On my other PC with phpunit 3.5 the example is still working.

Markus Bachmann

I think the problem is in the ExceptionController from the TwigBundle.

$count = 100;
$currentContent = '';
while (ob_get_level() && --$count) {
    $currentContent .= ob_get_clean();
}
Sebastian Bergmann

Fabien told me that he is investigating the issue. There may be a new Twig / Symfony 2 release soon to address it.

Tarjei Huse

A quick workaround: in TestCase.php:
if (ob_get_length() > 0 ) {
ob_end_clean();
}

J Kishore Kumar

After upgrading I could not successfully revert to 3.5.15. After a bit of trial and error, figured out the exact versions that works:

sudo pear install -f \
    phpunit/PHPUnit-3.5.15 \
    phpunit/DbUnit-1.0.3 \
    phpunit/PHPUnit_Selenium-1.0.3 \
    phpunit/PHP_CodeCoverage-1.0.5 \
    phpunit/File_Iterator-1.2.6

Edit: s/5.3.15/3.5.15/

Sebastian Blum

Thank you very much

Roderik van der Veer

Symfony 2.0.5 did not solve this

Marc Wensauer

We too have experienced hundreds of these "ob_end_clean(): failed to delete buffer" messages since moving from PHPUnit 3.5.15 to 3.6.0. We use the Zend Framework (v1.11.11) -- anybody else experiencing this? We have guarded our own few uses of ob_end_clean() like @tarjei mentions.

Using process isolation helps, but not completely (and the "RuntimeException" errors reported when using process isolation don't exactly help either).

Curious to know how pervasive this, and what, if anything, can be done about it (apart from staying on PHPUnit 3.5.15).

Mikko Hirvonen

I'm having the same issue. Reverting to 3.5.15 was a pain so I'm using the workaround for now.

Sebastian Bergmann

So the problem seems to be that code outside of PHPUnit stops the output buffering that was started by PHPUnit. There is nothing I can do about that in PHPUnit.

Sebastian Bergmann sebastianbergmann closed this November 03, 2011
Rubén Fanjul Estrada

This error is solved? i don't understand this:

A quick workaround: in TestCase.php:
if (ob_get_length() > 0 ) {
ob_end_clean();
}

Cheers!

Rubén Fanjul Estrada

ok, if the buffer is empty this file in the line 833, will broken

/usr/share/pear/PHPUnit/Framework/TestCase.php

then we need put this lines and check before remove it

if (ob_get_length() > 0 ) {
ob_end_clean();
}

with this, works for me

Cheers!

Sebastian Bergmann

I will not make a workaround in PHPUnit for an issue that is not a PHPUnit issue.

Michiel Missotten

I can understand your point of view when saying you will not patch an issue that is not a PHPUnit issue. But still, using a buffered output without checking if the buffer really exists and needs to be cleaned can be an issue in other cases.

Plus, the issue has been confirmed using Zend/Symfony2. Two of the most used php frameworks. It might be a small concession for better integration with those frameworks.

Anyway, as long as this issue will be "open" as "not resolved", I'll use the patched version locally.

Sebastian Bergmann

This is an issue in Zend Framework and Symfony. Why should that issue be worked around in PHPUnit?

Marc Wensauer

My earlier stated problem looks like it has nothing to do with Zend Framework, but is in fact a problem within our codebase, where we have a few unbalanced ob_*() calls (ZF's use of ob_*() calls looks balanced). Try grepping through your code for ob_ and it should be obvious where those calls are unmatched. PHPUnit is merely exposing the problem in your own code (or Symfony's possibly), so by using @tarjei's workaround, you're simply masking the problem.

Igor Wiedler

Issue in symfony tracker (for those looking for it): symfony/symfony#2531

Igor Wiedler

And for those wondering, the issue in symfony has now been fixed: symfony/symfony#2617.

Georgiana Gligor

thanks @justjkk ! your solution did the trick for me

James

are you saying that i cannot have ob_start within my code?

Maksim Kotlyar

FYI (not a problem of Phpunit):

you could get this error if you use newrelic:

<?php

ob_start();
var_dump(ob_get_level());
//1

newrelic_set_appname('foo')

var_dump(ob_get_level());
//0

Fabien Potencier fabpot referenced this issue from a commit in symfony/Form November 11, 2011
Fabien Potencier merged branch igorw/phpunit-ob-level (PR #2617)
Commits
-------

29e12af [TwigBundle] Extract output buffer cleaning to method
ed1a6c2 [TwigBundle] Do not clean output buffering below initial level

Discussion
----------

[TwigBundle] Do not clean output buffering below initial level

This resulted in issues with PHPUnit 3.6, which will buffer all output and clean them in the end. Since
we cleaned their buffer, the subsequent clean would raise a warning. This is documented in [issue 390](sebastianbergmann/phpunit#390) of
the PHPUnit tracker.

Closes #2531.

This also affects FOSRestBundle's ExceptionController /cc @lsmith.

---------------------------------------------------------------------------

by fabpot at 2011/11/11 07:33:24 -0800

I have a similar fix locally but I have not merged it yet as it looks a bit dirty (but I've not a better idea yet). Anyway, your PR is better than mine as you've added some unit tests already.
1940bec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.