wiki.techinc.nl/tests/phpunit/includes/deferred/RefreshSecondaryDataUpdateTest.php
Nikki Nikkhoui 8b43050319 Set logger to null in RefreshSecondaryataUpdateTest integration test
The code is appropriately logging when it encounters an exception.
However, the CI interprets that as an actual exception being thrown.
Setting the logger to null allows the CI to complete.

Bug: T248189
Change-Id: I9ce7c451b9951892e509afa048213e7691498e47
2020-03-27 10:56:05 -07:00

171 lines
5.5 KiB
PHP

<?php
use MediaWiki\MediaWikiServices;
use MediaWiki\Storage\DerivedPageDataUpdater;
use MediaWiki\Storage\MutableRevisionRecord;
use Psr\Log\NullLogger;
/**
* @covers RefreshSecondaryDataUpdate
*/
class RefreshSecondaryDataUpdateTest extends MediaWikiTestCase {
public function testSuccess() {
$services = MediaWikiServices::getInstance();
$lbFactory = $services->getDBLoadBalancerFactory();
$queue = JobQueueGroup::singleton()->get( 'refreshLinksPrioritized' );
$user = $this->getTestUser()->getUser();
$goodCalls = 0;
$goodUpdate = $this->getMockBuilder( DataUpdate::class )
->setMethods( [ 'doUpdate', 'setTransactionTicket' ] )
->getMock();
$goodTrxFname = get_class( $goodUpdate ) . '::doUpdate';
$goodUpdate->method( 'doUpdate' )
->willReturnCallback( function () use ( &$goodCalls, $lbFactory, $goodTrxFname ) {
// Update can commit since it owns the transaction
$lbFactory->commitMasterChanges( $goodTrxFname );
++$goodCalls;
} );
$goodUpdate->expects( $this->once() )
->method( 'setTransactionTicket' );
$updater = $this->getMockBuilder( DerivedPageDataUpdater::class )
->disableOriginalConstructor()
->setMethods( [ 'getSecondaryDataUpdates' ] )
->getMock();
$updater->method( 'getSecondaryDataUpdates' )
->willReturn( [ $goodUpdate ] );
$revision = $this->getMockBuilder( MutableRevisionRecord::class )
->disableOriginalConstructor()
->setMethods( [ 'getId' ] )
->getMock();
$revision->method( 'getId' )
->willReturn( 42 );
$dbw = wfGetDB( DB_MASTER );
$dbw->startAtomic( __METHOD__ );
$this->assertSame( 0, $queue->getSize() );
$this->assertSame( 0, DeferredUpdates::pendingUpdatesCount() );
$wikiPage = WikiPage::factory( Title::newFromText( 'TestPage' ) );
DeferredUpdates::addUpdate( new RefreshSecondaryDataUpdate(
$lbFactory,
$user,
$wikiPage,
$revision,
$updater,
[]
) );
$this->assertSame( 1, DeferredUpdates::pendingUpdatesCount() );
$this->assertSame( 0, $queue->getSize() );
$dbw->endAtomic( __METHOD__ ); // run updates
$this->assertSame( 0, DeferredUpdates::pendingUpdatesCount() );
$queue->flushCaches();
$this->assertSame( 0, $queue->getSize(), "Nothing failed; no enqueue" );
$this->assertSame( 1, $goodCalls );
}
function testEnqueueOnFailure() {
$services = MediaWikiServices::getInstance();
$lbFactory = $services->getDBLoadBalancerFactory();
$queue = JobQueueGroup::singleton()->get( 'refreshLinksPrioritized' );
$user = $this->getTestUser()->getUser();
// T248189: DeferredUpdate will log the exception, don't fail because of that.
$this->setLogger( 'exception', new NullLogger() );
$goodCalls = 0;
$goodUpdate = $this->getMockBuilder( DataUpdate::class )
->setMethods( [ 'doUpdate', 'setTransactionTicket' ] )
->getMock();
$goodTrxFname = get_class( $goodUpdate ) . '::doUpdate';
$goodUpdate->method( 'doUpdate' )
->willReturnCallback( function () use ( &$goodCalls, $lbFactory, $goodTrxFname ) {
// Update can commit since it owns the transaction
$lbFactory->commitMasterChanges( $goodTrxFname );
++$goodCalls;
} );
$goodUpdate->expects( $this->once() )
->method( 'setTransactionTicket' );
$badCalls = 0;
$badUpdate = $this->getMockBuilder( DataUpdate::class )
->setMethods( [ 'doUpdate', 'setTransactionTicket' ] )
->getMock();
$badTrxFname = get_class( $goodUpdate ) . '::doUpdate';
$badUpdate->expects( $this->once() )
->method( 'setTransactionTicket' );
$badUpdate->method( 'doUpdate' )
->willReturnCallback( function () use ( &$badCalls, $lbFactory, $badTrxFname ) {
// Update can commit since it owns the transaction
$lbFactory->commitMasterChanges( $badTrxFname );
++$badCalls;
throw new LogicException( 'We have a problem' );
} );
$updater = $this->getMockBuilder( DerivedPageDataUpdater::class )
->disableOriginalConstructor()
->setMethods( [ 'getSecondaryDataUpdates' ] )
->getMock();
$updater->method( 'getSecondaryDataUpdates' )
->willReturn( [ $goodUpdate, $badUpdate ] );
$revision = $this->getMockBuilder( MutableRevisionRecord::class )
->disableOriginalConstructor()
->setMethods( [ 'getId' ] )
->getMock();
$revision->method( 'getId' )
->willReturn( 42 );
$dbw = wfGetDB( DB_MASTER );
$dbw->startAtomic( __METHOD__ );
$goodCalls = 0;
$this->assertSame( 0, $queue->getSize() );
$this->assertSame( 0, DeferredUpdates::pendingUpdatesCount() );
$wikiPage = WikiPage::factory( Title::newFromText( 'TestPage' ) );
DeferredUpdates::addUpdate( new RefreshSecondaryDataUpdate(
$lbFactory,
$user,
$wikiPage,
$revision,
$updater,
[]
) );
$this->assertSame( 1, DeferredUpdates::pendingUpdatesCount() );
$this->assertSame( 0, $queue->getSize() );
try {
// Trigger deferred updates run to execute the update and secondary updates
$dbw->endAtomic( __METHOD__ );
// Callback rigged to fail
$this->fail( "Expected LogicException" );
} catch ( LogicException $e ) {
$this->assertSame( "We have a problem", $e->getMessage() );
}
$this->assertSame( 0, DeferredUpdates::pendingUpdatesCount() );
$queue->flushCaches();
$this->assertSame( 1, $queue->getSize(), "Update failed; job enqueued" );
$this->assertSame( 1, $goodCalls );
$this->assertSame( 1, $badCalls );
// Run the RefreshLinksJob
$this->runJobs();
$queue->flushCaches();
$this->assertSame( 0, $queue->getSize() );
}
private function runJobs() {
// Run the job queue
JobQueueGroup::destroySingletons();
$jobs = new RunJobs;
$jobs->loadParamsAndArgs( null, [ 'quiet' => true ], null );
$jobs->execute();
}
}