Merge "Add tests for tokenizer caching"

This commit is contained in:
jenkins-bot 2019-04-17 23:27:19 +00:00 committed by Gerrit Code Review
commit 968bd9b817
2 changed files with 51 additions and 7 deletions

View file

@ -66,6 +66,19 @@ class AbuseFilterTokenizer {
'rlike', 'irlike', 'regex', 'if', 'then', 'else', 'end',
];
/** @var BagOStuff */
public static $tokenizerCache;
/**
* Get a cache key used to store the tokenized code
*
* @param string $code Not yet tokenized
* @return string
*/
public static function getCacheKey( $code ) {
return wfGlobalCacheKey( __CLASS__, self::CACHE_VERSION, crc32( $code ) );
}
/**
* @param string $code
* @return array[]
@ -73,10 +86,8 @@ class AbuseFilterTokenizer {
* @throws AFPUserVisibleException
*/
public static function tokenize( $code ) {
static $tokenizerCache = null;
if ( !$tokenizerCache ) {
$tokenizerCache = ObjectCache::getLocalServerInstance( 'hash' );
if ( !self::$tokenizerCache ) {
self::$tokenizerCache = ObjectCache::getLocalServerInstance( 'hash' );
}
static $stats = null;
@ -85,9 +96,9 @@ class AbuseFilterTokenizer {
$stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
}
$cacheKey = wfGlobalCacheKey( __CLASS__, self::CACHE_VERSION, crc32( $code ) );
$cacheKey = self::getCacheKey( $code );
$tokens = $tokenizerCache->get( $cacheKey );
$tokens = self::$tokenizerCache->get( $cacheKey );
if ( $tokens ) {
$stats->increment( 'abusefilter.tokenizerCache.hit' );
@ -104,7 +115,7 @@ class AbuseFilterTokenizer {
$tokens[ $token->pos ] = [ $token, $curPos ];
} while ( $curPos !== $prevPos );
$tokenizerCache->set( $cacheKey, $tokens, 60 * 60 * 24 );
self::$tokenizerCache->set( $cacheKey, $tokens, 60 * 60 * 24 );
return $tokens;
}

View file

@ -143,4 +143,37 @@ class AbuseFilterTokenizerTest extends MediaWikiTestCase {
[ '"', 'readStringLiteral' ],
];
}
/**
* Test that tokenized code is saved in cache
*
* @param string $code To be tokenized
* @dataProvider provideCode
*/
public function testCaching( $code ) {
$cache = new HashBagOStuff();
$this->setService( 'LocalServerObjectCache', $cache );
$key = AbuseFilterTokenizer::getCacheKey( $code );
// Other tests may have already cached the same code.
$cache->delete( $key );
// Static hell makes code difficult to test...
AbuseFilterTokenizer::$tokenizerCache = null;
AbuseFilterTokenizer::tokenize( $code );
$this->assertNotFalse( $cache->get( $key ) );
}
/**
* Data provider for testCaching
*
* @return array
*/
public function provideCode() {
return [
[ '1 === 1' ],
[ 'added_lines irlike "test"' ],
[ 'edit_delta > 57 & action === "edit"' ],
[ '!("confirmed") in user_groups' ]
];
}
}