Fix so wfResetOutputBuffers doesn't break unit tests
authorBrad Jorsch <bjorsch@wikimedia.org>
Fri, 21 Aug 2015 16:01:10 +0000 (12:01 -0400)
committerBrad Jorsch <bjorsch@wikimedia.org>
Fri, 21 Aug 2015 16:24:07 +0000 (12:24 -0400)
If something being unit tested calls wfResetOutputBuffers(), it'll break
PHPUnit's attempt to capture output in order to fail tests. In the old
version we're currently using for Jenkins it will throw a warning
"ob_end_clean(): failed to delete buffer. No buffer to delete", while in
newer versions it'll detect that its buffer was removed and fail the
test as risky instead.

The solution here is to have MediaWikiTestCase add a buffer with a known
name in setUp() (and remove it in tearDown()), and have
wfResetOutputBuffers() stop when it sees that known name on the stack.

Bug: T109843
Change-Id: I8acd91ec9dd9c6d78a5d91d96202249f571d5d83

includes/GlobalFunctions.php
tests/phpunit/MediaWikiTestCase.php

index e158e5c..1a3ecc7 100644 (file)
@@ -2193,6 +2193,10 @@ function wfResetOutputBuffers( $resetGzipEncoding = true ) {
                        // output behavior.
                        break;
                }
+               if ( $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier' ) {
+                       // Unit testing barrier to prevent this function from breaking PHPUnit.
+                       break;
+               }
                if ( !ob_end_clean() ) {
                        // Could not remove output buffer handler; abort now
                        // to avoid getting in some kind of infinite loop.
index 43d8ce8..ac214a2 100644 (file)
@@ -208,6 +208,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                DeferredUpdates::clearPendingUpdates();
 
+               ob_start( 'MediaWikiTestCase::wfResetOutputBuffersBarrier' );
        }
 
        protected function addTmpFiles( $files ) {
@@ -215,6 +216,11 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
        }
 
        protected function tearDown() {
+               $status = ob_get_status();
+               if ( isset( $status['name'] ) && $status['name'] === 'MediaWikiTestCase::wfResetOutputBuffersBarrier' ) {
+                       ob_end_flush();
+               }
+
                $this->called['tearDown'] = true;
                // Cleaning up temporary files
                foreach ( $this->tmpFiles as $fileName ) {
@@ -1174,4 +1180,12 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase {
 
                self::assertFalse( self::tagMatch( $matcher, $actual, $isHtml ), $message );
        }
+
+       /**
+        * Used as a marker to prevent wfResetOutputBuffers from breaking PHPUnit.
+        * @return string
+        */
+       public static function wfResetOutputBuffersBarrier( $buffer ) {
+               return $buffer;
+       }
 }