newMultiServerLocalLoadBalancer(); $dbs = []; foreach ( $dbArray as $i => $info ) { $dbMock = $this->createMock( IDatabase::class ); $dbMock->method( 'getType' ) ->willReturn( 'mysql' ); $dbMock->method( 'query' ) ->willReturn( new FakeResultWrapper( [ [ 'pcount' => $i * 50 ] ] ) ); $dbs[] = $dbMock; } $lbMock = $this->createMock( ILoadBalancer::class ); $lbMock->method( 'getServerInfo' ) ->willReturnCallback( static function ( $i ) use ( $dbArray ) { return $dbArray[$i] ?? false; } ); $lbMock->method( 'getServerName' ) ->willReturnCallback( static function ( $i ) use ( $dbArray ) { return $dbArray[$i]['serverName'] ?? false; } ); $lbMock->method( 'getServerConnection' ) ->willReturnCallback( static function ( $i ) use ( $dbs ) { return $dbs[$i]; } ); $lbMock->method( 'getClusterName' ) ->willReturn( 'test-cluster' ); $wanMock = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] ); $loadMonitor = new LoadMonitor( $lbMock, new HashBagOStuff(), $wanMock, [] ); $weights = [ 0, 100, 100, 100, 100 ]; $loadMonitor->scaleLoads( $weights ); $this->assertSame( [ 0, 130, 111, 91, 72 ], $weights ); } public function testCircuitBreaking() { $dbArray = $this->newMultiServerLocalLoadBalancer(); $dbs = []; foreach ( $dbArray as $i => $info ) { $dbMock = $this->createMock( IDatabase::class ); $dbMock->method( 'getType' ) ->willReturn( 'mysql' ); $dbMock->method( 'query' ) ->willReturn( new FakeResultWrapper( [ [ 'pcount' => $i * 500 ] ] ) ); $dbs[] = $dbMock; } $lbMock = $this->createMock( ILoadBalancer::class ); $lbMock->method( 'getServerInfo' ) ->willReturnCallback( static function ( $i ) use ( $dbArray ) { return $dbArray[$i] ?? false; } ); $lbMock->method( 'getServerName' ) ->willReturnCallback( static function ( $i ) use ( $dbArray ) { return $dbArray[$i]['serverName'] ?? false; } ); $lbMock->method( 'getServerConnection' ) ->willReturnCallback( static function ( $i ) use ( $dbs ) { return $dbs[$i]; } ); $lbMock->method( 'getClusterName' ) ->willReturn( 'test-cluster' ); $wanMock = new WANObjectCache( [ 'cache' => new HashBagOStuff() ] ); $loadMonitor = new LoadMonitor( $lbMock, new HashBagOStuff(), $wanMock, [ 'maxConnCount' => 400 ] ); $weights = [ 0, 100, 100, 100, 100 ]; $this->expectException( DBUnexpectedError::class ); $loadMonitor->scaleLoads( $weights ); } private function newMultiServerLocalLoadBalancer() { $DBserver = 'localhost'; $DBport = '3306'; $DBname = 'wikidb'; $DBuser = 'wikiuser'; $DBpassword = 'wikidbpassword'; $DBtype = 'mysql'; $prefix = ''; return [ // Primary DB 0 => [ 'serverName' => 'db0', 'host' => $DBserver, 'port' => $DBport, 'dbname' => $DBname, 'tablePrefix' => $prefix, 'user' => $DBuser, 'password' => $DBpassword, 'type' => $DBtype, 'flags' => DBO_TRX, 'load' => 0, ], 1 => [ 'serverName' => 'db1', 'host' => $DBserver, 'port' => $DBport, 'dbname' => $DBname, 'tablePrefix' => $prefix, 'user' => $DBuser, 'password' => $DBpassword, 'type' => $DBtype, 'flags' => DBO_TRX, 'load' => 100, ], 2 => [ 'serverName' => 'db2', 'host' => $DBserver, 'port' => $DBport, 'dbname' => $DBname, 'tablePrefix' => $prefix, 'user' => $DBuser, 'password' => $DBpassword, 'type' => $DBtype, 'flags' => DBO_TRX, 'load' => 100, ], 3 => [ 'serverName' => 'db3', 'host' => $DBserver, 'port' => $DBport, 'dbname' => $DBname, 'tablePrefix' => $prefix, 'user' => $DBuser, 'password' => $DBpassword, 'type' => $DBtype, 'load' => 100, 'flags' => DBO_TRX, ], 4 => [ 'serverName' => 'db4', 'host' => $DBserver, 'port' => $DBport, 'dbname' => $DBname, 'tablePrefix' => $prefix, 'user' => $DBuser, 'password' => $DBpassword, 'type' => $DBtype, 'load' => 100, 'flags' => DBO_TRX, ], ]; } }