wiki.techinc.nl/tests/phpunit/includes/externalstore/ExternalStoreFactoryTest.php
Tim Starling 5e30a927bc tests: Make some PHPUnit data providers static
Just methods where adding "static" to the declaration was enough, I
didn't do anything with providers that used $this.

Initially by search and replace. There were many mistakes which I
found mostly by running the PHPStorm inspection which searches for
$this usage in a static method. Later I used the PHPStorm "make static"
action which avoids the more obvious mistakes.

Bug: T332865
Change-Id: I47ed6692945607dfa5c139d42edbd934fa4f3a36
2023-03-24 02:53:57 +00:00

148 lines
5.2 KiB
PHP

<?php
use MediaWiki\MainConfigNames;
use Wikimedia\Rdbms\LBFactory;
/**
* @covers ExternalStoreFactory
* @covers ExternalStoreAccess
*/
class ExternalStoreFactoryTest extends MediaWikiIntegrationTestCase {
public function testExternalStoreFactory_noStores1() {
$factory = new ExternalStoreFactory( [], [], 'test-id' );
$this->expectException( ExternalStoreException::class );
$factory->getStore( 'ForTesting' );
}
public function testExternalStoreFactory_noStores2() {
$factory = new ExternalStoreFactory( [], [], 'test-id' );
$this->expectException( ExternalStoreException::class );
$factory->getStore( 'foo' );
}
public static function provideStoreNames() {
yield 'Same case as construction' => [ 'ForTesting' ];
yield 'All lower case' => [ 'fortesting' ];
yield 'All upper case' => [ 'FORTESTING' ];
yield 'Mix of cases' => [ 'FOrTEsTInG' ];
}
/**
* @dataProvider provideStoreNames
*/
public function testExternalStoreFactory_someStore_protoMatch( $proto ) {
$factory = new ExternalStoreFactory( [ 'ForTesting' ], [], 'test-id' );
$store = $factory->getStore( $proto );
$this->assertInstanceOf( ExternalStoreForTesting::class, $store );
}
/**
* @dataProvider provideStoreNames
*/
public function testExternalStoreFactory_someStore_noProtoMatch( $proto ) {
$factory = new ExternalStoreFactory( [ 'SomeOtherClassName' ], [], 'test-id' );
$this->expectException( ExternalStoreException::class );
$factory->getStore( $proto );
}
/**
* @covers ExternalStoreFactory::getProtocols
* @covers ExternalStoreFactory::getWriteBaseUrls
* @covers ExternalStoreFactory::getStore
*/
public function testStoreFactoryBasic() {
$active = [ 'memory', 'mwstore' ];
$defaults = [ 'memory://cluster1', 'memory://cluster2', 'mwstore://memstore1' ];
$esFactory = new ExternalStoreFactory( $active, $defaults, 'db-prefix' );
$this->overrideConfigValue( MainConfigNames::FileBackends, [
[
'name' => 'memstore1',
'class' => MemoryFileBackend::class,
'domain' => 'its-all-in-your-head',
'readOnly' => 'reason is a lie',
'lockManager' => 'nullLockManager'
]
] );
$this->assertEquals( $active, $esFactory->getProtocols() );
$this->assertEquals( $defaults, $esFactory->getWriteBaseUrls() );
/** @var ExternalStoreMemory $store */
$store = $esFactory->getStore( 'memory' );
$this->assertInstanceOf( ExternalStoreMemory::class, $store );
$this->assertFalse( $store->isReadOnly( 'cluster1' ), "Location is writable" );
$this->assertFalse( $store->isReadOnly( 'cluster2' ), "Location is writable" );
$mwStore = $esFactory->getStore( 'mwstore' );
$this->assertTrue( $mwStore->isReadOnly( 'memstore1' ), "Location is read-only" );
$lb = $this->createMock( \Wikimedia\Rdbms\LoadBalancer::class );
$lb->method( 'getReadOnlyReason' )->willReturn( 'Locked' );
$lbFactory = $this->createMock( LBFactory::class );
$lbFactory->method( 'getExternalLB' )->willReturn( $lb );
$this->setService( 'DBLoadBalancerFactory', $lbFactory );
$active = [ 'db', 'mwstore' ];
$defaults = [ 'db://clusterX' ];
$esFactory = new ExternalStoreFactory( $active, $defaults, 'db-prefix' );
$this->assertEquals( $active, $esFactory->getProtocols() );
$this->assertEquals( $defaults, $esFactory->getWriteBaseUrls() );
$store->clear();
}
/**
* @covers ExternalStoreFactory::getStoreForUrl
* @covers ExternalStoreFactory::getStoreLocationFromUrl
*/
public function testStoreFactoryReadWrite() {
$active = [ 'memory' ]; // active store types
$defaults = [ 'memory://cluster1', 'memory://cluster2' ];
$esFactory = new ExternalStoreFactory( $active, $defaults, 'db-prefix' );
$access = new ExternalStoreAccess( $esFactory );
/** @var ExternalStoreMemory $storeLocal */
$storeLocal = $esFactory->getStore( 'memory' );
/** @var ExternalStoreMemory $storeOther */
$storeOther = $esFactory->getStore( 'memory', [ 'domain' => 'other' ] );
$this->assertInstanceOf( ExternalStoreMemory::class, $storeLocal );
$this->assertInstanceOf( ExternalStoreMemory::class, $storeOther );
$v1 = wfRandomString();
$v2 = wfRandomString();
$v3 = wfRandomString();
$this->assertFalse( $storeLocal->fetchFromURL( 'memory://cluster1/1' ) );
$url1 = 'memory://cluster1/1';
$this->assertEquals(
$url1,
$esFactory->getStoreForUrl( 'memory://cluster1' )
->store( $esFactory->getStoreLocationFromUrl( 'memory://cluster1' ), $v1 )
);
$this->assertEquals(
$v1,
$esFactory->getStoreForUrl( 'memory://cluster1/1' )
->fetchFromURL( 'memory://cluster1/1' )
);
$this->assertEquals( $v1, $storeLocal->fetchFromURL( 'memory://cluster1/1' ) );
$url2 = $access->insert( $v2 );
$url3 = $access->insert( $v3, [ 'domain' => 'other' ] );
$this->assertNotFalse( $url2 );
$this->assertNotFalse( $url3 );
// There is only one active store type
$this->assertEquals( $v2, $storeLocal->fetchFromURL( $url2 ) );
$this->assertEquals( $v3, $storeOther->fetchFromURL( $url3 ) );
$this->assertFalse( $storeOther->fetchFromURL( $url2 ) );
$this->assertFalse( $storeLocal->fetchFromURL( $url3 ) );
$res = $access->fetchFromURLs( [ $url1, $url2, $url3 ] );
$this->assertEquals( [ $url1 => $v1, $url2 => $v2, $url3 => false ], $res, "Local-only" );
$storeLocal->clear();
$storeOther->clear();
}
}