Allow resources to be salvaged across service resets.
[lhc/web/wiklou.git] / tests / phpunit / includes / MediaWikiServicesTest.php
index 6c38d50..cbb6059 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 use Liuggio\StatsdClient\Factory\StatsdDataFactory;
 use MediaWiki\MediaWikiServices;
+use MediaWiki\Services\DestructibleService;
+use MediaWiki\Services\SalvageableService;
 use MediaWiki\Services\ServiceDisabledException;
 
 /**
@@ -8,7 +10,7 @@ use MediaWiki\Services\ServiceDisabledException;
  *
  * @group MediaWiki
  */
-class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
+class MediaWikiServicesTest extends MediaWikiTestCase {
 
        /**
         * @return Config
@@ -65,9 +67,69 @@ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
                $newServices = $this->newMediaWikiServices();
                $oldServices = MediaWikiServices::forceGlobalInstance( $newServices );
 
+               $service1 = $this->getMock( SalvageableService::class );
+               $service1->expects( $this->never() )
+                       ->method( 'salvage' );
+
+               $newServices->defineService(
+                       'Test',
+                       function() use ( $service1 ) {
+                               return $service1;
+                       }
+               );
+
+               // force instantiation
+               $newServices->getService( 'Test' );
+
                MediaWikiServices::resetGlobalInstance( $this->newTestConfig() );
                $theServices = MediaWikiServices::getInstance();
 
+               $this->assertSame(
+                       $service1,
+                       $theServices->getService( 'Test' ),
+                       'service definition should survive reset'
+               );
+
+               $this->assertNotSame( $theServices, $newServices );
+               $this->assertNotSame( $theServices, $oldServices );
+
+               MediaWikiServices::forceGlobalInstance( $oldServices );
+       }
+
+       public function testResetGlobalInstance_quick() {
+               $newServices = $this->newMediaWikiServices();
+               $oldServices = MediaWikiServices::forceGlobalInstance( $newServices );
+
+               $service1 = $this->getMock( SalvageableService::class );
+               $service1->expects( $this->never() )
+                       ->method( 'salvage' );
+
+               $service2 = $this->getMock( SalvageableService::class );
+               $service2->expects( $this->once() )
+                       ->method( 'salvage' )
+                       ->with( $service1 );
+
+               // sequence of values the instantiator will return
+               $instantiatorReturnValues = [
+                       $service1,
+                       $service2,
+               ];
+
+               $newServices->defineService(
+                       'Test',
+                       function() use ( &$instantiatorReturnValues ) {
+                               return array_shift( $instantiatorReturnValues );
+                       }
+               );
+
+               // force instantiation
+               $newServices->getService( 'Test' );
+
+               MediaWikiServices::resetGlobalInstance( $this->newTestConfig(), 'quick' );
+               $theServices = MediaWikiServices::getInstance();
+
+               $this->assertSame( $service2, $theServices->getService( 'Test' ) );
+
                $this->assertNotSame( $theServices, $newServices );
                $this->assertNotSame( $theServices, $oldServices );
 
@@ -109,35 +171,42 @@ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
                }
 
                MediaWikiServices::forceGlobalInstance( $oldServices );
+               $newServices->destroy();
        }
 
        public function testResetChildProcessServices() {
                $newServices = $this->newMediaWikiServices();
                $oldServices = MediaWikiServices::forceGlobalInstance( $newServices );
 
-               $lbFactory = $this->getMockBuilder( 'LBFactorySimple' )
-                       ->disableOriginalConstructor()
-                       ->getMock();
+               $service1 = $this->getMock( DestructibleService::class );
+               $service1->expects( $this->once() )
+                       ->method( 'destroy' );
 
-               $lbFactory->expects( $this->once() )
+               $service2 = $this->getMock( DestructibleService::class );
+               $service2->expects( $this->never() )
                        ->method( 'destroy' );
 
-               $newServices->redefineService(
-                       'DBLoadBalancerFactory',
-                       function() use ( $lbFactory ) {
-                               return $lbFactory;
+               // sequence of values the instantiator will return
+               $instantiatorReturnValues = [
+                       $service1,
+                       $service2,
+               ];
+
+               $newServices->defineService(
+                       'Test',
+                       function() use ( &$instantiatorReturnValues ) {
+                               return array_shift( $instantiatorReturnValues );
                        }
                );
 
                // force the service to become active, so we can check that it does get destroyed
-               $oldLBFactory = $newServices->getService( 'DBLoadBalancerFactory' );
+               $oldTestService = $newServices->getService( 'Test' );
 
                MediaWikiServices::resetChildProcessServices();
                $finalServices = MediaWikiServices::getInstance();
 
-               $newLBFactory = $finalServices->getService( 'DBLoadBalancerFactory' );
-
-               $this->assertNotSame( $oldLBFactory, $newLBFactory );
+               $newTestService = $finalServices->getService( 'Test' );
+               $this->assertNotSame( $oldTestService, $newTestService );
 
                MediaWikiServices::forceGlobalInstance( $oldServices );
        }
@@ -200,6 +269,10 @@ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
 
                // All getters should be named just like the service, with "get" added.
                foreach ( $getServiceCases as $name => $case ) {
+                       if ( $name[0] === '_' ) {
+                               // Internal service, no getter
+                               continue;
+                       }
                        list( $service, $class ) = $case;
                        $getterCases[$name] = [
                                'get' . $service,
@@ -238,6 +311,10 @@ class MediaWikiServicesTest extends PHPUnit_Framework_TestCase {
                        'DBLoadBalancerFactory' => [ 'DBLoadBalancerFactory', 'LBFactory' ],
                        'DBLoadBalancer' => [ 'DBLoadBalancer', 'LoadBalancer' ],
                        'WatchedItemStore' => [ 'WatchedItemStore', WatchedItemStore::class ],
+                       'GenderCache' => [ 'GenderCache', GenderCache::class ],
+                       '_MediaWikiTitleCodec' => [ '_MediaWikiTitleCodec', MediaWikiTitleCodec::class ],
+                       'TitleFormatter' => [ 'TitleFormatter', TitleFormatter::class ],
+                       'TitleParser' => [ 'TitleParser', TitleParser::class ],
                ];
        }