/** * @covers ReplicatedBagOStuff::set */ public function testSet() { $key = wfRandomString(); $value = wfRandomString(); $this->cache->set($key, $value); // Write to master. $this->assertEquals($this->writeCache->get($key), $value); // Don't write to slave. Replication is deferred to backend. $this->assertEquals($this->readCache->get($key), false); }
public function testSetDelayed() { $key = wfRandomString(); $value = wfRandomString(); // XXX: DeferredUpdates bound to transactions in CLI mode $dbw = wfGetDB(DB_MASTER); $dbw->begin(); $this->cache->set($key, $value); // Set in tier 1 $this->assertEquals($value, $this->cache1->get($key), 'Written to tier 1'); // Not yet set in tier 2 $this->assertEquals(false, $this->cache2->get($key), 'Not written to tier 2'); $dbw->commit(); // Set in tier 2 $this->assertEquals($value, $this->cache2->get($key), 'Written to tier 2'); }
/** * @covers CachedBagOStuff::set * @covers CachedBagOStuff::delete */ public function testWriteCacheOnly() { $backend = new HashBagOStuff(); $cache = new CachedBagOStuff($backend); $cache->set('foo', 'bar', 0, CachedBagOStuff::WRITE_CACHE_ONLY); $this->assertEquals('bar', $cache->get('foo')); $this->assertFalse($backend->get('foo')); $cache->set('foo', 'old'); $this->assertEquals('old', $cache->get('foo')); $this->assertEquals('old', $backend->get('foo')); $cache->set('foo', 'new', 0, CachedBagOStuff::WRITE_CACHE_ONLY); $this->assertEquals('new', $cache->get('foo')); $this->assertEquals('old', $backend->get('foo')); $cache->delete('foo', CachedBagOStuff::WRITE_CACHE_ONLY); $this->assertEquals('old', $cache->get('foo')); // Reloaded from backend }
/** * Get an array of language names, indexed by code. * @param null|string $inLanguage Code of language in which to return the names * Use null for autonyms (native names) * @param string $include One of: * 'all' all available languages * 'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default) * 'mwfile' only if the language is in 'mw' *and* has a message file * @return array Language code => language name * @since 1.20 */ public static function fetchLanguageNames($inLanguage = null, $include = 'mw') { $cacheKey = $inLanguage === null ? 'null' : $inLanguage; $cacheKey .= ":{$include}"; if (self::$languageNameCache === null) { self::$languageNameCache = new HashBagOStuff(array('maxKeys' => 20)); } $ret = self::$languageNameCache->get($cacheKey); if (!$ret) { $ret = self::fetchLanguageNamesUncached($inLanguage, $include); self::$languageNameCache->set($cacheKey, $ret); } return $ret; }
/** * Check if a given user has permission to use this functionality. * @param User $user * @param bool $displayPassword If set, also check whether the user is allowed to reset the * password of another user and see the temporary password. * @return StatusValue */ public function isAllowed(User $user, $displayPassword = false) { $statuses = $this->permissionCache->get($user->getName()); if ($statuses) { list($status, $status2) = $statuses; } else { $resetRoutes = $this->config->get('PasswordResetRoutes'); $status = StatusValue::newGood(); if (!is_array($resetRoutes) || !in_array(true, array_values($resetRoutes), true)) { // Maybe password resets are disabled, or there are no allowable routes $status = StatusValue::newFatal('passwordreset-disabled'); } elseif (($providerStatus = $this->authManager->allowsAuthenticationDataChange(new TemporaryPasswordAuthenticationRequest(), false)) && !$providerStatus->isGood()) { // Maybe the external auth plugin won't allow local password changes $status = StatusValue::newFatal('resetpass_forbidden-reason', $providerStatus->getMessage()); } elseif (!$this->config->get('EnableEmail')) { // Maybe email features have been disabled $status = StatusValue::newFatal('passwordreset-emaildisabled'); } elseif (!$user->isAllowed('editmyprivateinfo')) { // Maybe not all users have permission to change private data $status = StatusValue::newFatal('badaccess'); } elseif ($user->isBlocked()) { // Maybe the user is blocked (check this here rather than relying on the parent // method as we have a more specific error message to use here $status = StatusValue::newFatal('blocked-mailpassword'); } $status2 = StatusValue::newGood(); if (!$user->isAllowed('passwordreset')) { $status2 = StatusValue::newFatal('badaccess'); } $this->permissionCache->set($user->getName(), [$status, $status2]); } if (!$displayPassword || !$status->isGood()) { return $status; } else { return $status2; } }
/** * @param string $title * @return bool */ public function isBadLink($title) { // Use get() to ensure it records as used for LRU. return $this->mBadLinks->get($title) !== false; }
/** * @covers BagOStuff::__construct * @covers BagOStuff::trackDuplicateKeys */ public function testReportDupes() { $logger = $this->getMock('Psr\\Log\\NullLogger'); $logger->expects($this->once())->method('warning')->with('Duplicate get(): "{key}" fetched {count} times', ['key' => 'foo', 'count' => 2]); $cache = new HashBagOStuff(['reportDupes' => true, 'asyncHandler' => 'DeferredUpdates::addCallableUpdate', 'logger' => $logger]); $cache->get('foo'); $cache->get('bar'); $cache->get('foo'); DeferredUpdates::doUpdates(); }
/** * Ensure maxKeys eviction prefers recently retrieved keys (LRU). * * @covers HashBagOStuff::__construct * @covers HashBagOStuff::doGet * @covers HashBagOStuff::hasKey */ public function testEvictionGet() { $cache = new HashBagOStuff(['maxKeys' => 3]); foreach (['foo', 'bar', 'baz'] as $key) { $cache->set($key, 1); } // Get existing key $cache->get('foo', 1); // Add a 4th key (beyond the allowed maximum) $cache->set('quux', 1); // Foo's life should have been extended over Bar foreach (['foo', 'baz', 'quux'] as $key) { $this->assertEquals(1, $cache->get($key), "Kept {$key}"); } $this->assertEquals(false, $cache->get('bar'), 'Evicted bar'); }
/** * @param User $user * @param LinkTarget $target * * @return WatchedItem|null */ private function getCached(User $user, LinkTarget $target) { return $this->cache->get($this->getCacheKey($user, $target)); }