private function setUpForeignRepo() { global $wgUploadDirectory; $this->setMwGlobals('wgForeignFileRepos', [['class' => 'ForeignAPIRepo', 'name' => 'wikimediacommons', 'backend' => 'wikimediacommons-backend', 'apibase' => 'https://commons.wikimedia.org/w/api.php', 'hashLevels' => 2, 'fetchDescription' => true, 'descriptionCacheExpiry' => 43200, 'apiThumbCacheExpiry' => 86400, 'directory' => $wgUploadDirectory]]); RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); }
protected function tearDown() { foreach ($this->savedGlobals as $var => $val) { $GLOBALS[$var] = $val; } // Restore backends RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); parent::tearDown(); }
public function tearDown() { foreach ($this->savedGlobals as $var => $val) { $GLOBALS[$var] = $val; } // Restore backends RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); $this->teardownUploadDir($this->uploadDir); }
/** * Initial setup, add .i18n. messages from $IP/extensions/DiscussionThreading/DiscussionThreading.i18n.php */ function NSFileRepoSetup() { global $wgLocalFileRepo; $wgLocalFileRepo['class'] = "NSLocalRepo"; RepoGroup::destroySingleton(); }
/** * Set up the global variables for a consistent environment for each test. * Ideally this should replace the global configuration entirely. * @param array $opts * @param string $config * @return RequestContext */ protected function setupGlobals($opts = array(), $config = '') { global $wgFileBackends; # Find out values for some special options. $lang = self::getOptionValue('language', $opts, 'en'); $variant = self::getOptionValue('variant', $opts, false); $maxtoclevel = self::getOptionValue('wgMaxTocLevel', $opts, 999); $linkHolderBatchSize = self::getOptionValue('wgLinkHolderBatchSize', $opts, 1000); $uploadDir = $this->getUploadDir(); if ($this->getCliArg('use-filebackend')) { if (self::$backendToUse) { $backend = self::$backendToUse; } else { $name = $this->getCliArg('use-filebackend'); $useConfig = array(); foreach ($wgFileBackends as $conf) { if ($conf['name'] == $name) { $useConfig = $conf; } } $useConfig['name'] = 'local-backend'; // swap name unset($useConfig['lockManager']); unset($useConfig['fileJournal']); $class = $useConfig['class']; self::$backendToUse = new $class($useConfig); $backend = self::$backendToUse; } } else { # Replace with a mock. We do not care about generating real # files on the filesystem, just need to expose the file # informations. $backend = new MockFileBackend(array('name' => 'local-backend', 'wikiId' => wfWikiId())); } $settings = array('wgLocalFileRepo' => array('class' => 'LocalRepo', 'name' => 'local', 'url' => 'http://example.com/images', 'hashLevels' => 2, 'transformVia404' => false, 'backend' => $backend), 'wgEnableUploads' => self::getOptionValue('wgEnableUploads', $opts, true), 'wgLanguageCode' => $lang, 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_', 'wgRawHtml' => self::getOptionValue('wgRawHtml', $opts, false), 'wgNamespacesWithSubpages' => array(NS_MAIN => isset($opts['subpage'])), 'wgAllowExternalImages' => self::getOptionValue('wgAllowExternalImages', $opts, true), 'wgThumbLimits' => array(self::getOptionValue('thumbsize', $opts, 180)), 'wgMaxTocLevel' => $maxtoclevel, 'wgUseTeX' => isset($opts['math']) || isset($opts['texvc']), 'wgMathDirectory' => $uploadDir . '/math', 'wgDefaultLanguageVariant' => $variant, 'wgLinkHolderBatchSize' => $linkHolderBatchSize, 'wgUseTidy' => isset($opts['tidy'])); if ($config) { $configLines = explode("\n", $config); foreach ($configLines as $line) { list($var, $value) = explode('=', $line, 2); $settings[$var] = eval("return {$value};"); // ??? } } $this->savedGlobals = array(); /** @since 1.20 */ Hooks::run('ParserTestGlobals', array(&$settings)); $langObj = Language::factory($lang); $settings['wgContLang'] = $langObj; $settings['wgLang'] = $langObj; $context = new RequestContext(); $settings['wgOut'] = $context->getOutput(); $settings['wgUser'] = $context->getUser(); $settings['wgRequest'] = $context->getRequest(); // We (re)set $wgThumbLimits to a single-element array above. $context->getUser()->setOption('thumbsize', 0); foreach ($settings as $var => $val) { if (array_key_exists($var, $GLOBALS)) { $this->savedGlobals[$var] = $GLOBALS[$var]; } $GLOBALS[$var] = $val; } MWTidy::destroySingleton(); MagicWord::clearCache(); # The entries saved into RepoGroup cache with previous globals will be wrong. RepoGroup::destroySingleton(); FileBackendGroup::destroySingleton(); # Create dummy files in storage $this->setupUploads(); # Publish the articles after we have the final language set $this->publishTestArticles(); MessageCache::destroyInstance(); return $context; }
/** * Enable expansion of local URLs. * * In order to output stand-alone content with all absolute links, it is * necessary to expand local URLs. MediaWiki tries to do this in a few * places by sniffing into the 'action' GET request parameter, but this * fails in many ways. This function tries to remedy this. * * This function pre-expands all base URL fragments used by MediaWiki, * and also enables URL expansion in the Wikilog::GetLocalURL hook. * The original values of all URLs are saved when $enable = true, and * restored back when $enabled = false. * * The proper way to use this function is: * @code * $saveExpUrls = WikilogParser::expandLocalUrls(); * # ...code that uses $wgParser in order to parse articles... * WikilogParser::expandLocalUrls( $saveExpUrls ); * @endcode * * @note Using this function changes the behavior of Parser. When enabled, * parsed content should be cached under a different key. */ public static function expandLocalUrls( $enable = true ) { global $wgScriptPath, $wgUploadPath, $wgStylePath, $wgMathPath, $wgLocalFileRepo; static $originalPaths = null; $prev = self::$expandingUrls; if ( $enable ) { if ( !self::$expandingUrls ) { self::$expandingUrls = true; # Save original values. $originalPaths = array( $wgScriptPath, $wgUploadPath, $wgStylePath, $wgMathPath, $wgLocalFileRepo['url'] ); # Expand paths. $wgScriptPath = wfExpandUrl( $wgScriptPath ); $wgUploadPath = wfExpandUrl( $wgUploadPath ); $wgStylePath = wfExpandUrl( $wgStylePath ); $wgMathPath = wfExpandUrl( $wgMathPath ); $wgLocalFileRepo['url'] = wfExpandUrl( $wgLocalFileRepo['url'] ); # Destroy existing RepoGroup, if any. RepoGroup::destroySingleton(); } } else { if ( self::$expandingUrls ) { self::$expandingUrls = false; # Restore original values. list( $wgScriptPath, $wgUploadPath, $wgStylePath, $wgMathPath, $wgLocalFileRepo['url'] ) = $originalPaths; # Destroy existing RepoGroup, if any. RepoGroup::destroySingleton(); } } return $prev; }
/** * Restore default values and perform any necessary clean-up * after each test runs. */ protected function teardownGlobals() { $this->teardownUploads(); foreach ($this->savedGlobals as $var => $val) { $GLOBALS[$var] = $val; } RepoGroup::destroySingleton(); LinkCache::singleton()->clear(); }
/** * Do any setup which can be done once for all tests, independent of test * options, except for database setup. * * Public setup functions in this class return a ScopedCallback object. When * this object is destroyed by going out of scope, teardown of the * corresponding test setup is performed. * * Teardown objects may be chained by passing a ScopedCallback from a * previous setup stage as the $nextTeardown parameter. This enforces the * convention that teardown actions are taken in reverse order to the * corresponding setup actions. When $nextTeardown is specified, a * ScopedCallback will be returned which first tears down the current * setup stage, and then tears down the previous setup stage which was * specified by $nextTeardown. * * @param ScopedCallback|null $nextTeardown * @return ScopedCallback */ public function staticSetup($nextTeardown = null) { // A note on coding style: // The general idea here is to keep setup code together with // corresponding teardown code, in a fine-grained manner. We have two // arrays: $setup and $teardown. The code snippets in the $setup array // are executed at the end of the method, before it returns, and the // code snippets in the $teardown array are executed in reverse order // when the Wikimedia\ScopedCallback object is consumed. // Because it is a common operation to save, set and restore global // variables, we have an additional convention: when the array key of // $setup is a string, the string is taken to be the name of the global // variable, and the element value is taken to be the desired new value. // It's acceptable to just do the setup immediately, instead of adding // a closure to $setup, except when the setup action depends on global // variable initialisation being done first. In this case, you have to // append a closure to $setup after the global variable is appended. // When you add to setup functions in this class, please keep associated // setup and teardown actions together in the source code, and please // add comments explaining why the setup action is necessary. $setup = []; $teardown = []; $teardown[] = $this->markSetupDone('staticSetup'); // Some settings which influence HTML output $setup['wgSitename'] = 'MediaWiki'; $setup['wgServer'] = 'http://example.org'; $setup['wgServerName'] = 'example.org'; $setup['wgScriptPath'] = ''; $setup['wgScript'] = '/index.php'; $setup['wgResourceBasePath'] = ''; $setup['wgStylePath'] = '/skins'; $setup['wgExtensionAssetsPath'] = '/extensions'; $setup['wgArticlePath'] = '/wiki/$1'; $setup['wgActionPaths'] = []; $setup['wgVariantArticlePath'] = false; $setup['wgUploadNavigationUrl'] = false; $setup['wgCapitalLinks'] = true; $setup['wgNoFollowLinks'] = true; $setup['wgNoFollowDomainExceptions'] = ['no-nofollow.org']; $setup['wgExternalLinkTarget'] = false; $setup['wgExperimentalHtmlIds'] = false; $setup['wgLocaltimezone'] = 'UTC'; $setup['wgHtml5'] = true; $setup['wgDisableLangConversion'] = false; $setup['wgDisableTitleConversion'] = false; // "extra language links" // see https://gerrit.wikimedia.org/r/111390 $setup['wgExtraInterlanguageLinkPrefixes'] = ['mul']; // All FileRepo changes should be done here by injecting services, // there should be no need to change global variables. RepoGroup::setSingleton($this->createRepoGroup()); $teardown[] = function () { RepoGroup::destroySingleton(); }; // Set up null lock managers $setup['wgLockManagers'] = [['name' => 'fsLockManager', 'class' => 'NullLockManager'], ['name' => 'nullLockManager', 'class' => 'NullLockManager']]; $reset = function () { LockManagerGroup::destroySingletons(); }; $setup[] = $reset; $teardown[] = $reset; // This allows article insertion into the prefixed DB $setup['wgDefaultExternalStore'] = false; // This might slightly reduce memory usage $setup['wgAdaptiveMessageCache'] = true; // This is essential and overrides disabling of database messages in TestSetup $setup['wgUseDatabaseMessages'] = true; $reset = function () { MessageCache::destroyInstance(); }; $setup[] = $reset; $teardown[] = $reset; // It's not necessary to actually convert any files $setup['wgSVGConverter'] = 'null'; $setup['wgSVGConverters'] = ['null' => 'echo "1">$output']; // Fake constant timestamp Hooks::register('ParserGetVariableValueTs', 'ParserTestRunner::getFakeTimestamp'); $teardown[] = function () { Hooks::clear('ParserGetVariableValueTs'); }; $this->appendNamespaceSetup($setup, $teardown); // Set up interwikis and append teardown function $teardown[] = $this->setupInterwikis(); // This affects title normalization in links. It invalidates // MediaWikiTitleCodec objects. $setup['wgLocalInterwikis'] = ['local', 'mi']; $reset = function () { $this->resetTitleServices(); }; $setup[] = $reset; $teardown[] = $reset; // Set up a mock MediaHandlerFactory MediaWikiServices::getInstance()->disableService('MediaHandlerFactory'); MediaWikiServices::getInstance()->redefineService('MediaHandlerFactory', function () { return new MockMediaHandlerFactory(); }); $teardown[] = function () { MediaWikiServices::getInstance()->resetServiceForTesting('MediaHandlerFactory'); }; // SqlBagOStuff broke when using temporary tables on r40209 (bug 15892). // It seems to have been fixed since (r55079?), but regressed at some point before r85701. // This works around it for now... global $wgObjectCaches; $setup['wgObjectCaches'] = [CACHE_DB => $wgObjectCaches['hash']] + $wgObjectCaches; if (isset(ObjectCache::$instances[CACHE_DB])) { $savedCache = ObjectCache::$instances[CACHE_DB]; ObjectCache::$instances[CACHE_DB] = new HashBagOStuff(); $teardown[] = function () use($savedCache) { ObjectCache::$instances[CACHE_DB] = $savedCache; }; } $teardown[] = $this->executeSetupSnippets($setup); // Schedule teardown snippets in reverse order return $this->createTeardownObject($teardown, $nextTeardown); }