X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=tests%2Fphpunit%2FMediaWikiTestCase.php;h=8dfe628a3ff40bd595fb14970a7c31c7b4c9e235;hb=fa40f8f1451a1b6771718b8fde691fca42c4f9c2;hp=9f3aa11a7ca462a98972a86b2e671b1b5af2ae96;hpb=1b855688586f29206a64eb975c2dd3d4e252ad84;p=lhc%2Fweb%2Fwiklou.git diff --git a/tests/phpunit/MediaWikiTestCase.php b/tests/phpunit/MediaWikiTestCase.php index 9f3aa11a7c..8dfe628a3f 100644 --- a/tests/phpunit/MediaWikiTestCase.php +++ b/tests/phpunit/MediaWikiTestCase.php @@ -127,6 +127,42 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { self::prepareServices( new GlobalVarConfig() ); } + /** + * Convenience method for getting an immutable test user + * + * @since 1.28 + * + * @param string[] $groups Groups the test user should be in. + * @return TestUser + */ + public static function getTestUser( $groups = [] ) { + return TestUserRegistry::getImmutableTestUser( $groups ); + } + + /** + * Convenience method for getting a mutable test user + * + * @since 1.28 + * + * @param string[] $groups Groups the test user should be added in. + * @return TestUser + */ + public static function getMutableTestUser( $groups = [] ) { + return TestUserRegistry::getMutableTestUser( __CLASS__, $groups ); + } + + /** + * Convenience method for getting an immutable admin test user + * + * @since 1.28 + * + * @param string[] $groups Groups the test user should be added to. + * @return TestUser + */ + public static function getTestSysop() { + return self::getTestUser( [ 'sysop', 'bureaucrat' ] ); + } + /** * Prepare service configuration for unit testing. * @@ -221,6 +257,9 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $defaultOverrides->set( 'ObjectCaches', $objectCaches ); $defaultOverrides->set( 'MainCacheType', CACHE_NONE ); + // Use a fast hash algorithm to hash passwords. + $defaultOverrides->set( 'PasswordDefault', 'A' ); + $testConfig = $customOverrides ? new MultiConfig( [ $customOverrides, $defaultOverrides, $baseConfig ] ) : new MultiConfig( [ $defaultOverrides, $baseConfig ] ); @@ -318,7 +357,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { $needsResetDB = false; - if ( $this->needsDB() ) { + if ( !self::$dbSetup || $this->needsDB() ) { // set up a DB connection for this test to use self::$useTemporaryTables = !$this->getCliArg( 'use-normal-tables' ); @@ -597,6 +636,29 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } } + /** + * Check if we can back up a value by performing a shallow copy. + * Values which fail this test are copied recursively. + * + * @param mixed $value + * @return bool True if a shallow copy will do; false if a deep copy + * is required. + */ + private static function canShallowCopy( $value ) { + if ( is_scalar( $value ) || $value === null ) { + return true; + } + if ( is_array( $value ) ) { + foreach ( $value as $subValue ) { + if ( !is_scalar( $subValue ) && $subValue !== null ) { + return false; + } + } + return true; + } + return false; + } + /** * Stashes the global, will be restored in tearDown() * @@ -632,13 +694,22 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { // NOTE: we serialize then unserialize the value in case it is an object // this stops any objects being passed by reference. We could use clone // and if is_object but this does account for objects within objects! - try { - $this->mwGlobals[$globalKey] = unserialize( serialize( $GLOBALS[$globalKey] ) ); - } - // NOTE; some things such as Closures are not serializable - // in this case just set the value! - catch ( Exception $e ) { + if ( self::canShallowCopy( $GLOBALS[$globalKey] ) ) { $this->mwGlobals[$globalKey] = $GLOBALS[$globalKey]; + } elseif ( + // Many MediaWiki types are safe to clone. These are the + // ones that are most commonly stashed. + $GLOBALS[$globalKey] instanceof Language || + $GLOBALS[$globalKey] instanceof User || + $GLOBALS[$globalKey] instanceof FauxRequest + ) { + $this->mwGlobals[$globalKey] = clone $GLOBALS[$globalKey]; + } else { + try { + $this->mwGlobals[$globalKey] = unserialize( serialize( $GLOBALS[$globalKey] ) ); + } catch ( Exception $e ) { + $this->mwGlobals[$globalKey] = $GLOBALS[$globalKey]; + } } } } @@ -848,7 +919,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { protected function insertPage( $pageName, $text = 'Sample page for unit test.' ) { $title = Title::newFromText( $pageName, 0 ); - $user = User::newFromName( 'UTSysop' ); + $user = static::getTestSysop()->getUser(); $comment = __METHOD__ . ': Sample page for unit test.'; // Avoid memory leak...? @@ -899,36 +970,33 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { # Insert 0 user to prevent FK violations # Anonymous user - $this->db->insert( 'user', [ - 'user_id' => 0, - 'user_name' => 'Anonymous' ], __METHOD__, [ 'IGNORE' ] ); + if ( !$this->db->selectField( 'user', '1', [ 'user_id' => 0 ] ) ) { + $this->db->insert( 'user', [ + 'user_id' => 0, + 'user_name' => 'Anonymous' ], __METHOD__, [ 'IGNORE' ] ); + } # Insert 0 page to prevent FK violations # Blank page - $this->db->insert( 'page', [ - 'page_id' => 0, - 'page_namespace' => 0, - 'page_title' => ' ', - 'page_restrictions' => null, - 'page_is_redirect' => 0, - 'page_is_new' => 0, - 'page_random' => 0, - 'page_touched' => $this->db->timestamp(), - 'page_latest' => 0, - 'page_len' => 0 ], __METHOD__, [ 'IGNORE' ] ); + if ( !$this->db->selectField( 'page', '1', [ 'page_id' => 0 ] ) ) { + $this->db->insert( 'page', [ + 'page_id' => 0, + 'page_namespace' => 0, + 'page_title' => ' ', + 'page_restrictions' => null, + 'page_is_redirect' => 0, + 'page_is_new' => 0, + 'page_random' => 0, + 'page_touched' => $this->db->timestamp(), + 'page_latest' => 0, + 'page_len' => 0 ], __METHOD__, [ 'IGNORE' ] ); + } } User::resetIdByNameCache(); // Make sysop user - $user = User::newFromName( 'UTSysop' ); - - if ( $user->idForName() == 0 ) { - $user->addToDatabase(); - TestUser::setPasswordForUser( $user, 'UTSysopPassword' ); - $user->addGroup( 'sysop' ); - $user->addGroup( 'bureaucrat' ); - } + $user = static::getTestSysop()->getUser(); // Make 1 page with 1 revision $page = WikiPage::factory( Title::newFromText( 'UTPage' ) ); @@ -1147,11 +1215,7 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { // If any of the user tables were marked as used, we should clear all of them. if ( array_intersect( $tablesUsed, $userTables ) ) { $tablesUsed = array_unique( array_merge( $tablesUsed, $userTables ) ); - - // Totally clear User class in-process cache to avoid CAS errors - TestingAccessWrapper::newFromClass( 'User' ) - ->getInProcessCache() - ->clear(); + TestUserRegistry::clear(); } $truncate = in_array( $db->getType(), [ 'oracle', 'mysql' ] ); @@ -1586,32 +1650,6 @@ abstract class MediaWikiTestCase extends PHPUnit_Framework_TestCase { } } - /** - * Check whether we have the 'gzip' commandline utility, will skip - * the test whenever "gzip -V" fails. - * - * Result is cached at the process level. - * - * @return bool - * - * @since 1.21 - */ - protected function checkHasGzip() { - static $haveGzip; - - if ( $haveGzip === null ) { - $retval = null; - wfShellExec( 'gzip -V', $retval ); - $haveGzip = ( $retval === 0 ); - } - - if ( !$haveGzip ) { - $this->markTestSkipped( "Skip test, requires the gzip utility in PATH" ); - } - - return $haveGzip; - } - /** * Check if $extName is a loaded PHP extension, will skip the * test whenever it is not loaded.