Merge "maintenance: Script to rename titles for Unicode uppercasing changes"
[lhc/web/wiklou.git] / tests / phpunit / includes / externalstore / ExternalStoreFactoryTest.php
1 <?php
2
3 /**
4 * @covers ExternalStoreFactory
5 * @covers ExternalStoreAccess
6 */
7 class ExternalStoreFactoryTest extends MediaWikiTestCase {
8
9 use MediaWikiCoversValidator;
10
11 /**
12 * @expectedException ExternalStoreException
13 */
14 public function testExternalStoreFactory_noStores1() {
15 $factory = new ExternalStoreFactory( [], [], 'test-id' );
16 $factory->getStore( 'ForTesting' );
17 }
18
19 /**
20 * @expectedException ExternalStoreException
21 */
22 public function testExternalStoreFactory_noStores2() {
23 $factory = new ExternalStoreFactory( [], [], 'test-id' );
24 $factory->getStore( 'foo' );
25 }
26
27 public function provideStoreNames() {
28 yield 'Same case as construction' => [ 'ForTesting' ];
29 yield 'All lower case' => [ 'fortesting' ];
30 yield 'All upper case' => [ 'FORTESTING' ];
31 yield 'Mix of cases' => [ 'FOrTEsTInG' ];
32 }
33
34 /**
35 * @dataProvider provideStoreNames
36 */
37 public function testExternalStoreFactory_someStore_protoMatch( $proto ) {
38 $factory = new ExternalStoreFactory( [ 'ForTesting' ], [], 'test-id' );
39 $store = $factory->getStore( $proto );
40 $this->assertInstanceOf( ExternalStoreForTesting::class, $store );
41 }
42
43 /**
44 * @dataProvider provideStoreNames
45 * @expectedException ExternalStoreException
46 */
47 public function testExternalStoreFactory_someStore_noProtoMatch( $proto ) {
48 $factory = new ExternalStoreFactory( [ 'SomeOtherClassName' ], [], 'test-id' );
49 $factory->getStore( $proto );
50 }
51
52 /**
53 * @covers ExternalStoreFactory::getProtocols
54 * @covers ExternalStoreFactory::getWriteBaseUrls
55 * @covers ExternalStoreFactory::getStore
56 */
57 public function testStoreFactoryBasic() {
58 $active = [ 'memory' ];
59 $defaults = [ 'memory://cluster1', 'memory://cluster2' ];
60 $esFactory = new ExternalStoreFactory( $active, $defaults, 'db-prefix' );
61
62 $this->assertEquals( $active, $esFactory->getProtocols() );
63 $this->assertEquals( $defaults, $esFactory->getWriteBaseUrls() );
64
65 /** @var ExternalStoreMemory $store */
66 $store = $esFactory->getStore( 'memory' );
67 $this->assertInstanceOf( ExternalStoreMemory::class, $store );
68 $this->assertEquals( false, $store->isReadOnly( 'cluster1' ) );
69 $this->assertEquals( false, $store->isReadOnly( 'cluster2' ) );
70 $this->assertEquals( true, $store->isReadOnly( 'clusterOld' ) );
71
72 $lb = $this->getMockBuilder( \Wikimedia\Rdbms\LoadBalancer::class )
73 ->disableOriginalConstructor()->getMock();
74 $lb->expects( $this->any() )->method( 'getReadOnlyReason' )->willReturn( 'Locked' );
75 $lbFactory = $this->getMockBuilder( \Wikimedia\Rdbms\LBFactory::class )
76 ->disableOriginalConstructor()->getMock();
77 $lbFactory->expects( $this->any() )->method( 'getExternalLB' )->willReturn( $lb );
78
79 $this->setService( 'DBLoadBalancerFactory', $lbFactory );
80
81 $active = [ 'db', 'mwstore' ];
82 $defaults = [ 'db://clusterX' ];
83 $esFactory = new ExternalStoreFactory( $active, $defaults, 'db-prefix' );
84 $this->assertEquals( $active, $esFactory->getProtocols() );
85 $this->assertEquals( $defaults, $esFactory->getWriteBaseUrls() );
86
87 $store->clear();
88 }
89
90 /**
91 * @covers ExternalStoreFactory::getStoreForUrl
92 * @covers ExternalStoreFactory::getStoreLocationFromUrl
93 */
94 public function testStoreFactoryReadWrite() {
95 $active = [ 'memory' ]; // active store types
96 $defaults = [ 'memory://cluster1', 'memory://cluster2' ];
97 $esFactory = new ExternalStoreFactory( $active, $defaults, 'db-prefix' );
98 $access = new ExternalStoreAccess( $esFactory );
99
100 /** @var ExternalStoreMemory $storeLocal */
101 $storeLocal = $esFactory->getStore( 'memory' );
102 /** @var ExternalStoreMemory $storeOther */
103 $storeOther = $esFactory->getStore( 'memory', [ 'domain' => 'other' ] );
104 $this->assertInstanceOf( ExternalStoreMemory::class, $storeLocal );
105 $this->assertInstanceOf( ExternalStoreMemory::class, $storeOther );
106
107 $v1 = wfRandomString();
108 $v2 = wfRandomString();
109 $v3 = wfRandomString();
110
111 $this->assertEquals( false, $storeLocal->fetchFromURL( 'memory://cluster1/1' ) );
112
113 $url1 = 'memory://cluster1/1';
114 $this->assertEquals(
115 $url1,
116 $esFactory->getStoreForUrl( 'memory://cluster1' )
117 ->store( $esFactory->getStoreLocationFromUrl( 'memory://cluster1' ), $v1 )
118 );
119 $this->assertEquals(
120 $v1,
121 $esFactory->getStoreForUrl( 'memory://cluster1/1' )
122 ->fetchFromURL( 'memory://cluster1/1' )
123 );
124 $this->assertEquals( $v1, $storeLocal->fetchFromURL( 'memory://cluster1/1' ) );
125
126 $url2 = $access->insert( $v2 );
127 $url3 = $access->insert( $v3, [ 'domain' => 'other' ] );
128 $this->assertNotFalse( $url2 );
129 $this->assertNotFalse( $url3 );
130 // There is only one active store type
131 $this->assertEquals( $v2, $storeLocal->fetchFromURL( $url2 ) );
132 $this->assertEquals( $v3, $storeOther->fetchFromURL( $url3 ) );
133 $this->assertEquals( false, $storeOther->fetchFromURL( $url2 ) );
134 $this->assertEquals( false, $storeLocal->fetchFromURL( $url3 ) );
135
136 $res = $access->fetchFromURLs( [ $url1, $url2, $url3 ] );
137 $this->assertEquals( [ $url1 => $v1, $url2 => $v2, $url3 => false ], $res, "Local-only" );
138
139 $storeLocal->clear();
140 $storeOther->clear();
141 }
142 }