rdbms: add LoadBalancer::getLocalDomainId() method
authorAaron Schulz <aschulz@wikimedia.org>
Fri, 12 Jan 2018 23:57:23 +0000 (15:57 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Sat, 13 Jan 2018 20:52:59 +0000 (12:52 -0800)
This returns the default domain without getting a connection

Also avoid assuming that LoadBalancerTest has the same DB handle
as other tests even though it makes its own LB object. That breaks
if temporary tables are used.

Change-Id: I351d42de38b3126222c5a40627a2a12f76a60939

includes/libs/rdbms/loadbalancer/LoadBalancer.php
tests/phpunit/includes/db/LoadBalancerTest.php

index a75dc4d..e80b952 100644 (file)
@@ -242,6 +242,17 @@ class LoadBalancer implements ILoadBalancer {
                }
        }
 
+       /**
+        * Get the local (and default) database domain ID of connection handles
+        *
+        * @see DatabaseDomain
+        * @return string Database domain ID; this specifies DB name, schema, and table prefix
+        * @since 1.31
+        */
+       public function getLocalDomainID() {
+               return $this->localDomain->getId();
+       }
+
        /**
         * Get a LoadMonitor instance
         *
index 5fd33dc..54aa2ac 100644 (file)
@@ -1,8 +1,9 @@
 <?php
 
 use Wikimedia\Rdbms\DBError;
-use Wikimedia\Rdbms\IDatabase;
 use Wikimedia\Rdbms\LoadBalancer;
+use Wikimedia\Rdbms\DatabaseDomain;
+use Wikimedia\Rdbms\Database;
 
 /**
  * Holds tests for LoadBalancer MediaWiki class.
@@ -35,6 +36,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                        [
                                'host'        => $wgDBserver,
                                'dbname'      => $wgDBname,
+                               'tablePrefix' => $this->dbPrefix(),
                                'user'        => $wgDBuser,
                                'password'    => $wgDBpassword,
                                'type'        => $wgDBtype,
@@ -46,9 +48,13 @@ class LoadBalancerTest extends MediaWikiTestCase {
 
                $lb = new LoadBalancer( [
                        'servers' => $servers,
-                       'localDomain' => wfWikiID()
+                       'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() )
                ] );
 
+               $ld = DatabaseDomain::newFromId( $lb->getLocalDomainID() );
+               $this->assertEquals( $wgDBname, $ld->getDatabase(), 'local domain DB set' );
+               $this->assertEquals( $this->dbPrefix(), $ld->getTablePrefix(), 'local domain prefix set' );
+
                $dbw = $lb->getConnection( DB_MASTER );
                $this->assertTrue( $dbw->getLBInfo( 'master' ), 'master shows as master' );
                $this->assertTrue( $dbw->getFlag( $dbw::DBO_TRX ), "DBO_TRX set on master" );
@@ -81,6 +87,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                        [ // master
                                'host'        => $wgDBserver,
                                'dbname'      => $wgDBname,
+                               'tablePrefix' => $this->dbPrefix(),
                                'user'        => $wgDBuser,
                                'password'    => $wgDBpassword,
                                'type'        => $wgDBtype,
@@ -91,6 +98,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
                        [ // emulated replica
                                'host'        => $wgDBserver,
                                'dbname'      => $wgDBname,
+                               'tablePrefix' => $this->dbPrefix(),
                                'user'        => $wgDBuser,
                                'password'    => $wgDBpassword,
                                'type'        => $wgDBtype,
@@ -102,7 +110,7 @@ class LoadBalancerTest extends MediaWikiTestCase {
 
                $lb = new LoadBalancer( [
                        'servers' => $servers,
-                       'localDomain' => wfWikiID(),
+                       'localDomain' => new DatabaseDomain( $wgDBname, null, $this->dbPrefix() ),
                        'loadMonitorClass' => 'LoadMonitorNull'
                ] );
 
@@ -140,9 +148,9 @@ class LoadBalancerTest extends MediaWikiTestCase {
                $lb->closeAll();
        }
 
-       private function assertWriteForbidden( IDatabase $db ) {
+       private function assertWriteForbidden( Database $db ) {
                try {
-                       $db->delete( 'user', [ 'user_id' => 57634126 ], 'TEST' );
+                       $db->delete( 'some_table', [ 'id' => 57634126 ], __METHOD__ );
                        $this->fail( 'Write operation should have failed!' );
                } catch ( DBError $ex ) {
                        // check that the exception message contains "Write operation"
@@ -157,9 +165,26 @@ class LoadBalancerTest extends MediaWikiTestCase {
                }
        }
 
-       private function assertWriteAllowed( IDatabase $db ) {
+       private function assertWriteAllowed( Database $db ) {
+               $table = $db->tableName( 'some_table' );
                try {
-                       $this->assertNotSame( false, $db->delete( 'user', [ 'user_id' => 57634126 ] ) );
+                       $db->dropTable( 'some_table' ); // clear for sanity
+                       // Use only basic SQL and trivial types for these queries for compatibility
+                       $this->assertNotSame(
+                               false,
+                               $db->query( "CREATE TABLE $table (id INT, time INT)", __METHOD__ ),
+                               "table created"
+                       );
+                       $this->assertNotSame(
+                               false,
+                               $db->query( "DELETE FROM $table WHERE id=57634126", __METHOD__ ),
+                               "delete query"
+                       );
+                       $this->assertNotSame(
+                               false,
+                               $db->query( "DROP TABLE $table", __METHOD__ ),
+                               "table dropped"
+                       );
                } finally {
                        $db->rollback( __METHOD__, 'flush' );
                }