X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=tests%2Fphpunit%2Fincludes%2Flibs%2Frdbms%2Fdatabase%2FDatabaseTest.php;h=94b4e0d9953edfeb6398d27c074023efbbaab9e3;hb=d4c31cf84115a7e447fdf1284c823000238981f9;hp=e1315067291d034b40deff826bb57ce4f600aa0b;hpb=a5f91ac24f8253807966140fd3c8666ff6bc2f5c;p=lhc%2Fweb%2Fwiklou.git diff --git a/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php b/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php index e131506729..94b4e0d995 100644 --- a/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php +++ b/tests/phpunit/includes/libs/rdbms/database/DatabaseTest.php @@ -1,11 +1,16 @@ db = new DatabaseTestHelper( __CLASS__ . '::' . $this->getName() ); } + /** + * @dataProvider provideAddQuotes + * @covers Wikimedia\Rdbms\Database::factory + */ + public function testFactory() { + $m = Database::NEW_UNCONNECTED; // no-connect mode + $p = [ 'host' => 'localhost', 'user' => 'me', 'password' => 'myself', 'dbname' => 'i' ]; + + $this->assertInstanceOf( DatabaseMysqli::class, Database::factory( 'mysqli', $p, $m ) ); + $this->assertInstanceOf( DatabaseMysqli::class, Database::factory( 'MySqli', $p, $m ) ); + $this->assertInstanceOf( DatabaseMysqli::class, Database::factory( 'MySQLi', $p, $m ) ); + $this->assertInstanceOf( DatabasePostgres::class, Database::factory( 'postgres', $p, $m ) ); + $this->assertInstanceOf( DatabasePostgres::class, Database::factory( 'Postgres', $p, $m ) ); + + $x = $p + [ 'port' => 10000, 'UseWindowsAuth' => false ]; + $this->assertInstanceOf( DatabaseMssql::class, Database::factory( 'mssql', $x, $m ) ); + + $x = $p + [ 'dbFilePath' => 'some/file.sqlite' ]; + $this->assertInstanceOf( DatabaseSqlite::class, Database::factory( 'sqlite', $x, $m ) ); + $x = $p + [ 'dbDirectory' => 'some/file' ]; + $this->assertInstanceOf( DatabaseSqlite::class, Database::factory( 'sqlite', $x, $m ) ); + } + public static function provideAddQuotes() { return [ [ null, 'NULL' ], @@ -149,28 +177,27 @@ class DatabaseTest extends PHPUnit_Framework_TestCase { public function testTransactionIdle() { $db = $this->db; - $db->setFlag( DBO_TRX ); + $db->clearFlag( DBO_TRX ); $called = false; $flagSet = null; - $db->onTransactionIdle( - function () use ( $db, &$flagSet, &$called ) { - $called = true; - $flagSet = $db->getFlag( DBO_TRX ); - }, - __METHOD__ - ); - $this->assertFalse( $flagSet, 'DBO_TRX off in callback' ); - $this->assertTrue( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' ); + $callback = function () use ( $db, &$flagSet, &$called ) { + $called = true; + $flagSet = $db->getFlag( DBO_TRX ); + }; + + $db->onTransactionIdle( $callback, __METHOD__ ); $this->assertTrue( $called, 'Callback reached' ); + $this->assertFalse( $flagSet, 'DBO_TRX off in callback' ); + $this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX still default' ); - $db->clearFlag( DBO_TRX ); $flagSet = null; - $db->onTransactionIdle( - function () use ( $db, &$flagSet ) { - $flagSet = $db->getFlag( DBO_TRX ); - }, - __METHOD__ - ); + $called = false; + $db->startAtomic( __METHOD__ ); + $db->onTransactionIdle( $callback, __METHOD__ ); + $this->assertFalse( $called, 'Callback not reached during TRX' ); + $db->endAtomic( __METHOD__ ); + + $this->assertTrue( $called, 'Callback reached after COMMIT' ); $this->assertFalse( $flagSet, 'DBO_TRX off in callback' ); $this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' ); @@ -184,6 +211,56 @@ class DatabaseTest extends PHPUnit_Framework_TestCase { $this->assertFalse( $db->getFlag( DBO_TRX ), 'DBO_TRX restored to default' ); } + /** + * @covers Wikimedia\Rdbms\Database::onTransactionIdle + * @covers Wikimedia\Rdbms\Database::runOnTransactionIdleCallbacks + */ + public function testTransactionIdle_TRX() { + $db = $this->getMockDB( [ 'isOpen', 'ping' ] ); + $db->method( 'isOpen' )->willReturn( true ); + $db->method( 'ping' )->willReturn( true ); + $db->setFlag( DBO_TRX ); + + $lbFactory = LBFactorySingle::newFromConnection( $db ); + // Ask for the connection so that LB sets internal state + // about this connection being the master connection + $lb = $lbFactory->getMainLB(); + $conn = $lb->openConnection( $lb->getWriterIndex() ); + $this->assertSame( $db, $conn, 'Same DB instance' ); + $this->assertTrue( $db->getFlag( DBO_TRX ), 'DBO_TRX is set' ); + + $called = false; + $flagSet = null; + $callback = function () use ( $db, &$flagSet, &$called ) { + $called = true; + $flagSet = $db->getFlag( DBO_TRX ); + }; + + $db->onTransactionIdle( $callback, __METHOD__ ); + $this->assertTrue( $called, 'Called when idle if DBO_TRX is set' ); + $this->assertFalse( $flagSet, 'DBO_TRX off in callback' ); + $this->assertTrue( $db->getFlag( DBO_TRX ), 'DBO_TRX still default' ); + + $called = false; + $lbFactory->beginMasterChanges( __METHOD__ ); + $db->onTransactionIdle( $callback, __METHOD__ ); + $this->assertFalse( $called, 'Not called when lb-transaction is active' ); + + $lbFactory->commitMasterChanges( __METHOD__ ); + $this->assertTrue( $called, 'Called when lb-transaction is committed' ); + + $called = false; + $lbFactory->beginMasterChanges( __METHOD__ ); + $db->onTransactionIdle( $callback, __METHOD__ ); + $this->assertFalse( $called, 'Not called when lb-transaction is active' ); + + $lbFactory->rollbackMasterChanges( __METHOD__ ); + $this->assertFalse( $called, 'Not called when lb-transaction is rolled back' ); + + $lbFactory->commitMasterChanges( __METHOD__ ); + $this->assertFalse( $called, 'Not called in next round commit' ); + } + /** * @covers Wikimedia\Rdbms\Database::onTransactionPreCommitOrIdle * @covers Wikimedia\Rdbms\Database::runOnTransactionPreCommitCallbacks @@ -222,12 +299,13 @@ class DatabaseTest extends PHPUnit_Framework_TestCase { * @covers Wikimedia\Rdbms\Database::runOnTransactionPreCommitCallbacks */ public function testTransactionPreCommitOrIdle_TRX() { - $db = $this->getMockDB( [ 'isOpen' ] ); + $db = $this->getMockDB( [ 'isOpen', 'ping' ] ); $db->method( 'isOpen' )->willReturn( true ); + $db->method( 'ping' )->willReturn( true ); $db->setFlag( DBO_TRX ); $lbFactory = LBFactorySingle::newFromConnection( $db ); - // Ask for the connectin so that LB sets internal state + // Ask for the connection so that LB sets internal state // about this connection being the master connection $lb = $lbFactory->getMainLB(); $conn = $lb->openConnection( $lb->getWriterIndex() ); @@ -235,18 +313,29 @@ class DatabaseTest extends PHPUnit_Framework_TestCase { $this->assertTrue( $db->getFlag( DBO_TRX ), 'DBO_TRX is set' ); $called = false; - $db->onTransactionPreCommitOrIdle( - function () use ( &$called ) { - $called = true; - } - ); - $this->assertFalse( $called, 'Not called when idle if DBO_TRX is set' ); + $callback = function () use ( &$called ) { + $called = true; + }; + $db->onTransactionPreCommitOrIdle( $callback, __METHOD__ ); + $this->assertTrue( $called, 'Called when idle if DBO_TRX is set' ); + $called = false; $lbFactory->beginMasterChanges( __METHOD__ ); + $db->onTransactionPreCommitOrIdle( $callback, __METHOD__ ); $this->assertFalse( $called, 'Not called when lb-transaction is active' ); - $lbFactory->commitMasterChanges( __METHOD__ ); $this->assertTrue( $called, 'Called when lb-transaction is committed' ); + + $called = false; + $lbFactory->beginMasterChanges( __METHOD__ ); + $db->onTransactionPreCommitOrIdle( $callback, __METHOD__ ); + $this->assertFalse( $called, 'Not called when lb-transaction is active' ); + + $lbFactory->rollbackMasterChanges( __METHOD__ ); + $this->assertFalse( $called, 'Not called when lb-transaction is rolled back' ); + + $lbFactory->commitMasterChanges( __METHOD__ ); + $this->assertFalse( $called, 'Not called in next round commit' ); } /** @@ -370,10 +459,34 @@ class DatabaseTest extends PHPUnit_Framework_TestCase { $this->assertFalse( (bool)$db->trxLevel(), "Transaction cleared." ); } + /** + * @covers Wikimedia\Rdbms\Database::getScopedLockAndFlush + * @covers Wikimedia\Rdbms\Database::lock + * @covers Wikimedia\Rdbms\Database::unlock + * @covers Wikimedia\Rdbms\Database::lockIsFree + */ public function testGetScopedLock() { $db = $this->getMockDB( [ 'isOpen' ] ); $db->method( 'isOpen' )->willReturn( true ); + $this->assertEquals( 0, $db->trxLevel() ); + $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) ); + $this->assertEquals( true, $db->lock( 'x', __METHOD__ ) ); + $this->assertEquals( false, $db->lockIsFree( 'x', __METHOD__ ) ); + $this->assertEquals( true, $db->unlock( 'x', __METHOD__ ) ); + $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) ); + $this->assertEquals( 0, $db->trxLevel() ); + + $db->setFlag( DBO_TRX ); + $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) ); + $this->assertEquals( true, $db->lock( 'x', __METHOD__ ) ); + $this->assertEquals( false, $db->lockIsFree( 'x', __METHOD__ ) ); + $this->assertEquals( true, $db->unlock( 'x', __METHOD__ ) ); + $this->assertEquals( true, $db->lockIsFree( 'x', __METHOD__ ) ); + $db->clearFlag( DBO_TRX ); + + $this->assertEquals( 0, $db->trxLevel() ); + $db->setFlag( DBO_TRX ); try { $this->badLockingMethodImplicit( $db ); @@ -445,6 +558,32 @@ class DatabaseTest extends PHPUnit_Framework_TestCase { $this->assertEquals( $origTrx, $db->getFlag( DBO_TRX ) ); } + /** + * @expectedException UnexpectedValueException + * @covers Wikimedia\Rdbms\Database::setFlag + */ + public function testDBOIgnoreSet() { + $db = $this->getMockBuilder( DatabaseMysqli::class ) + ->disableOriginalConstructor() + ->setMethods( null ) + ->getMock(); + + $db->setFlag( Database::DBO_IGNORE ); + } + + /** + * @expectedException UnexpectedValueException + * @covers Wikimedia\Rdbms\Database::clearFlag + */ + public function testDBOIgnoreClear() { + $db = $this->getMockBuilder( DatabaseMysqli::class ) + ->disableOriginalConstructor() + ->setMethods( null ) + ->getMock(); + + $db->clearFlag( Database::DBO_IGNORE ); + } + /** * @covers Wikimedia\Rdbms\Database::tablePrefix * @covers Wikimedia\Rdbms\Database::dbSchema