[MCR] fix RevisionStore::checkDatabaseWikiId for DB names with dashes.
authoraddshore <addshorewiki@gmail.com>
Wed, 3 Jan 2018 14:42:13 +0000 (14:42 +0000)
committerAddshore <addshorewiki@gmail.com>
Thu, 4 Jan 2018 17:18:41 +0000 (17:18 +0000)
This is a quick hack, for a proper solution see I6a98684af1d7

Bug: T183914
Change-Id: I45a151a332145438c484e02bbe96cd85dd602b9e

includes/Storage/RevisionStore.php
tests/phpunit/includes/Storage/RevisionStoreDbTest.php

index ce56efc..2e953fc 100644 (file)
@@ -1476,10 +1476,20 @@ class RevisionStore implements IDBAccessObject, RevisionFactory, RevisionLookup
                $storeWiki = $storeWiki ?: wfWikiID();
                $dbWiki = $dbWiki ?: wfWikiID();
 
-               if ( $dbWiki !== $storeWiki ) {
-                       throw new MWException( "RevisionStore for $storeWiki "
-                               . "cannot be used with a DB connection for $dbWiki" );
+               if ( $dbWiki === $storeWiki ) {
+                       return;
+               }
+
+               // HACK: counteract encoding imposed by DatabaseDomain
+               $storeWiki = str_replace( '?h', '-', $storeWiki );
+               $dbWiki = str_replace( '?h', '-', $dbWiki );
+
+               if ( $dbWiki === $storeWiki ) {
+                       return;
                }
+
+               throw new MWException( "RevisionStore for $storeWiki "
+                       . "cannot be used with a DB connection for $dbWiki" );
        }
 
        /**
index ee8fdc7..28a8d88 100644 (file)
@@ -4,17 +4,26 @@ namespace MediaWiki\Tests\Storage;
 
 use CommentStoreComment;
 use Exception;
+use HashBagOStuff;
 use InvalidArgumentException;
 use MediaWiki\Linker\LinkTarget;
 use MediaWiki\MediaWikiServices;
 use MediaWiki\Storage\IncompleteRevisionException;
 use MediaWiki\Storage\MutableRevisionRecord;
 use MediaWiki\Storage\RevisionRecord;
+use MediaWiki\Storage\RevisionStore;
 use MediaWiki\Storage\SlotRecord;
+use MediaWiki\Storage\SqlBlobStore;
 use MediaWikiTestCase;
 use Revision;
 use TestUserRegistry;
 use Title;
+use WANObjectCache;
+use Wikimedia\Rdbms\Database;
+use Wikimedia\Rdbms\DatabaseSqlite;
+use Wikimedia\Rdbms\FakeResultWrapper;
+use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\TransactionProfiler;
 use WikiPage;
 use WikitextContent;
 
@@ -23,6 +32,107 @@ use WikitextContent;
  */
 class RevisionStoreDbTest extends MediaWikiTestCase {
 
+       /**
+        * @return LoadBalancer
+        */
+       private function getLoadBalancerMock( array $server ) {
+               $lb = $this->getMockBuilder( LoadBalancer::class )
+                       ->setMethods( [ 'reallyOpenConnection' ] )
+                       ->setConstructorArgs( [ [ 'servers' => [ $server ] ] ] )
+                       ->getMock();
+
+               $lb->method( 'reallyOpenConnection' )->willReturnCallback(
+                       function ( array $server, $dbNameOverride = false ) {
+                               return $this->getDatabaseMock( $server );
+                       }
+               );
+
+               return $lb;
+       }
+
+       /**
+        * @return Database
+        */
+       private function getDatabaseMock( array $params ) {
+               $db = $this->getMockBuilder( DatabaseSqlite::class )
+                       ->setMethods( [ 'select', 'doQuery', 'open', 'closeConnection', 'isOpen' ] )
+                       ->setConstructorArgs( [ $params ] )
+                       ->getMock();
+
+               $db->method( 'select' )->willReturn( new FakeResultWrapper( [] ) );
+               $db->method( 'isOpen' )->willReturn( true );
+
+               return $db;
+       }
+
+       public function provideDomainCheck() {
+               yield [ false, 'test', '' ];
+               yield [ 'test', 'test', '' ];
+
+               yield [ false, 'test', 'foo_' ];
+               yield [ 'test-foo_', 'test', 'foo_' ];
+
+               yield [ false, 'dash-test', '' ];
+               yield [ 'dash-test', 'dash-test', '' ];
+
+               yield [ false, 'underscore_test', 'foo_' ];
+               yield [ 'underscore_test-foo_', 'underscore_test', 'foo_' ];
+       }
+
+       /**
+        * @dataProvider provideDomainCheck
+        * @covers \MediaWiki\Storage\RevisionStore::checkDatabaseWikiId
+        */
+       public function testDomainCheck( $wikiId, $dbName, $dbPrefix ) {
+               $this->setMwGlobals(
+                       [
+                               'wgDBname' => $dbName,
+                               'wgDBprefix' => $dbPrefix,
+                       ]
+               );
+
+               $loadBalancer = $this->getLoadBalancerMock(
+                       [
+                               'host' => '*dummy*',
+                               'dbDirectory' => '*dummy*',
+                               'user' => 'test',
+                               'password' => 'test',
+                               'flags' => 0,
+                               'variables' => [],
+                               'schema' => '',
+                               'cliMode' => true,
+                               'agent' => '',
+                               'load' => 100,
+                               'profiler' => null,
+                               'trxProfiler' => new TransactionProfiler(),
+                               'connLogger' => new \Psr\Log\NullLogger(),
+                               'queryLogger' => new \Psr\Log\NullLogger(),
+                               'errorLogger' => new \Psr\Log\NullLogger(),
+                               'type' => 'test',
+                               'dbname' => $dbName,
+                               'tablePrefix' => $dbPrefix,
+                       ]
+               );
+               $db = $loadBalancer->getConnection( DB_REPLICA );
+
+               $blobStore = $this->getMockBuilder( SqlBlobStore::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $store = new RevisionStore(
+                       $loadBalancer,
+                       $blobStore,
+                       new WANObjectCache( [ 'cache' => new HashBagOStuff() ] ),
+                       $wikiId
+               );
+
+               $count = $store->countRevisionsByPageId( $db, 0 );
+
+               // Dummy check to make PhpUnit happy. We are really only interested in
+               // countRevisionsByPageId not failing due to the DB domain check.
+               $this->assertSame( 0, $count );
+       }
+
        private function assertLinkTargetsEqual( LinkTarget $l1, LinkTarget $l2 ) {
                $this->assertEquals( $l1->getDBkey(), $l2->getDBkey() );
                $this->assertEquals( $l1->getNamespace(), $l2->getNamespace() );