Add a VariablesBlobStore service

Change-Id: If0c1eab2391819f8b4c801d12275d9ec14490f7a
This commit is contained in:
Daimona Eaytoy 2020-09-29 16:52:05 +02:00 committed by Jforrester
parent dfeff89317
commit c52ef337d7
16 changed files with 159 additions and 72 deletions

View file

@ -69,7 +69,8 @@
"LinkBatchFactory",
"PermissionManager",
"AbuseFilterPermissionManager",
"AbuseFilterConsequencesRegistry"
"AbuseFilterConsequencesRegistry",
"AbuseFilterVariablesBlobStore"
]
},
"AbuseFilter": {
@ -177,6 +178,7 @@
"MediaWiki\\Extension\\AbuseFilter\\FilterStore": "includes/FilterStore.php",
"MediaWiki\\Extension\\AbuseFilter\\ConsequencesFactory": "includes/ConsequencesFactory.php",
"MediaWiki\\Extension\\AbuseFilter\\ConsequencesLookup": "includes/ConsequencesLookup.php",
"MediaWiki\\Extension\\AbuseFilter\\VariablesBlobStore": "includes/VariablesBlobStore.php",
"MediaWiki\\Extension\\AbuseFilter\\AbuseLogger": "includes/AbuseLogger.php",
"MediaWiki\\Extension\\AbuseFilter\\AbuseLoggerFactory": "includes/AbuseLoggerFactory.php",
"MediaWiki\\Extension\\AbuseFilter\\ConsequencesRegistry": "includes/ConsequencesRegistry.php",

View file

@ -3,8 +3,6 @@
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Storage\BlobAccessException;
use MediaWiki\Storage\BlobStore;
/**
* This class contains most of the business logic of AbuseFilter. It consists of
@ -69,57 +67,6 @@ class AbuseFilter {
return $runner->run();
}
/**
* Store a var dump to a BlobStore.
*
* @param AbuseFilterVariableHolder $vars
* @param bool $global
*
* @return string Address of the record
*/
public static function storeVarDump( AbuseFilterVariableHolder $vars, $global = false ) {
global $wgAbuseFilterCentralDB;
// Get all variables yet set and compute old and new wikitext if not yet done
// as those are needed for the diff view on top of the abuse log pages
$vars = $vars->dumpAllVars( [ 'old_wikitext', 'new_wikitext' ] );
// Vars is an array with native PHP data types (non-objects) now
$text = FormatJson::encode( $vars );
$blobStoreFactory = \MediaWiki\MediaWikiServices::getInstance()->getBlobStoreFactory();
$dbDomain = $global ? $wgAbuseFilterCentralDB : false;
$blobStore = $blobStoreFactory->newBlobStore( $dbDomain );
$hints = [
BlobStore::DESIGNATION_HINT => 'AbuseFilter',
BlobStore::MODEL_HINT => 'AbuseFilter',
];
return $blobStore->storeBlob( $text, $hints );
}
/**
* Retrieve a var dump from a BlobStore.
*
* @param string $address
*
* @return AbuseFilterVariableHolder
*/
public static function loadVarDump( string $address ) : AbuseFilterVariableHolder {
$blobStore = \MediaWiki\MediaWikiServices::getInstance()->getBlobStore();
try {
$blob = $blobStore->getBlob( $address );
} catch ( BlobAccessException $ex ) {
return new AbuseFilterVariableHolder;
}
$vars = FormatJson::decode( $blob, true );
$obj = AbuseFilterVariableHolder::newFromArray( $vars );
$obj->translateDeprecatedVars();
return $obj;
}
/**
* @param string $action
* @param MessageLocalizer|null $localizer

View file

@ -165,4 +165,11 @@ class AbuseFilterServices {
public static function getUpdateHitCountWatcher() : UpdateHitCountWatcher {
return MediaWikiServices::getInstance()->getService( UpdateHitCountWatcher::SERVICE_NAME );
}
/**
* @return VariablesBlobStore
*/
public static function getVariablesBlobStore() : VariablesBlobStore {
return MediaWikiServices::getInstance()->getService( VariablesBlobStore::SERVICE_NAME );
}
}

View file

@ -35,6 +35,8 @@ class AbuseLogger {
private $centralDBManager;
/** @var FilterLookup */
private $filterLookup;
/** @var VariablesBlobStore */
private $varBlobStore;
/** @var ILoadBalancer */
private $loadBalancer;
/** @var ServiceOptions */
@ -47,6 +49,7 @@ class AbuseLogger {
/**
* @param CentralDBManager $centralDBManager
* @param FilterLookup $filterLookup
* @param VariablesBlobStore $varBlobStore
* @param ILoadBalancer $loadBalancer
* @param ServiceOptions $options
* @param string $wikiID
@ -58,6 +61,7 @@ class AbuseLogger {
public function __construct(
CentralDBManager $centralDBManager,
FilterLookup $filterLookup,
VariablesBlobStore $varBlobStore,
ILoadBalancer $loadBalancer,
ServiceOptions $options,
string $wikiID,
@ -71,6 +75,7 @@ class AbuseLogger {
}
$this->centralDBManager = $centralDBManager;
$this->filterLookup = $filterLookup;
$this->varBlobStore = $varBlobStore;
$this->loadBalancer = $loadBalancer;
$options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
$this->options = $options;
@ -198,7 +203,7 @@ class AbuseLogger {
global $wgAbuseFilterAflFilterMigrationStage;
$writeNewSchema = $wgAbuseFilterAflFilterMigrationStage & SCHEMA_COMPAT_WRITE_NEW;
$varDump = AbuseFilter::storeVarDump( $this->vars );
$varDump = $this->varBlobStore->storeVarDump( $this->vars );
$loggedIDs = [];
foreach ( $logRows as $data ) {
@ -268,7 +273,7 @@ class AbuseLogger {
*/
private function insertGlobalLogEntries( array $centralLogRows, IDatabase $fdb ) : array {
$this->vars->computeDBVars();
$globalVarDump = AbuseFilter::storeVarDump( $this->vars, true );
$globalVarDump = $this->varBlobStore->storeVarDump( $this->vars, true );
foreach ( $centralLogRows as $index => $data ) {
$centralLogRows[$index]['afl_var_dump'] = $globalVarDump;
}

View file

@ -15,6 +15,8 @@ class AbuseLoggerFactory {
private $centralDBManager;
/** @var FilterLookup */
private $filterLookup;
/** @var VariablesBlobStore */
private $varBlobStore;
/** @var ILoadBalancer */
private $loadBalancer;
/** @var ServiceOptions */
@ -27,6 +29,7 @@ class AbuseLoggerFactory {
/**
* @param CentralDBManager $centralDBManager
* @param FilterLookup $filterLookup
* @param VariablesBlobStore $varBlobStore
* @param ILoadBalancer $loadBalancer
* @param ServiceOptions $options
* @param string $wikiID
@ -35,6 +38,7 @@ class AbuseLoggerFactory {
public function __construct(
CentralDBManager $centralDBManager,
FilterLookup $filterLookup,
VariablesBlobStore $varBlobStore,
ILoadBalancer $loadBalancer,
ServiceOptions $options,
string $wikiID,
@ -42,6 +46,7 @@ class AbuseLoggerFactory {
) {
$this->centralDBManager = $centralDBManager;
$this->filterLookup = $filterLookup;
$this->varBlobStore = $varBlobStore;
$this->loadBalancer = $loadBalancer;
$this->options = $options;
$this->wikiID = $wikiID;
@ -62,6 +67,7 @@ class AbuseLoggerFactory {
return new AbuseLogger(
$this->centralDBManager,
$this->filterLookup,
$this->varBlobStore,
$this->loadBalancer,
$this->options,
$this->wikiID,

View file

@ -2,7 +2,6 @@
namespace MediaWiki\Extension\AbuseFilter\Api;
use AbuseFilter;
use AbuseFilterVariableHolder;
use ApiBase;
use ApiResult;
@ -54,7 +53,7 @@ class CheckMatch extends ApiBase {
$this->dieWithError( [ 'apierror-abusefilter-nosuchlogid', $params['logid'] ], 'nosuchlogid' );
}
$vars = AbuseFilter::loadVarDump( $row->afl_var_dump );
$vars = AbuseFilterServices::getVariablesBlobStore()->loadVarDump( $row->afl_var_dump );
}
if ( $vars === null ) {
throw new LogicException( 'Impossible.' );

View file

@ -317,7 +317,7 @@ class QueryAbuseLog extends ApiQueryBase {
if ( $fld_details ) {
$entry['details'] = [];
if ( $canSeeDetails ) {
$vars = AbuseFilter::loadVarDump( $row->afl_var_dump );
$vars = AbuseFilterServices::getVariablesBlobStore()->loadVarDump( $row->afl_var_dump );
$entry['details'] = $vars->exportAllVars();
}
}

View file

@ -23,6 +23,7 @@ use MediaWiki\Extension\AbuseFilter\FilterValidator;
use MediaWiki\Extension\AbuseFilter\Hooks\AbuseFilterHookRunner;
use MediaWiki\Extension\AbuseFilter\KeywordsManager;
use MediaWiki\Extension\AbuseFilter\Parser\ParserFactory;
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
use MediaWiki\Extension\AbuseFilter\Watcher\EmergencyWatcher;
use MediaWiki\Extension\AbuseFilter\Watcher\UpdateHitCountWatcher;
use MediaWiki\Logger\LoggerFactory;
@ -198,6 +199,7 @@ return [
return new AbuseLoggerFactory(
$services->get( CentralDBManager::SERVICE_NAME ),
$services->get( FilterLookup::SERVICE_NAME ),
$services->get( VariablesBlobStore::SERVICE_NAME ),
$services->getDBLoadBalancer(),
new ServiceOptions(
AbuseLogger::CONSTRUCTOR_OPTIONS,
@ -213,6 +215,13 @@ return [
$services->get( CentralDBManager::SERVICE_NAME )
);
},
VariablesBlobStore::SERVICE_NAME => function ( MediaWikiServices $services ): VariablesBlobStore {
return new VariablesBlobStore(
$services->getBlobStoreFactory(),
$services->getBlobStore(),
$services->getMainConfig()->get( 'AbuseFilterCentralDB' )
);
},
];
// @codeCoverageIgnoreEnd

View file

@ -0,0 +1,82 @@
<?php
namespace MediaWiki\Extension\AbuseFilter;
use AbuseFilterVariableHolder;
use FormatJson;
use MediaWiki\Storage\BlobAccessException;
use MediaWiki\Storage\BlobStore;
use MediaWiki\Storage\BlobStoreFactory;
/**
* This service is used to store and load var dumps to a BlobStore
*/
class VariablesBlobStore {
public const SERVICE_NAME = 'AbuseFilterVariablesBlobStore';
/** @var BlobStoreFactory */
private $blobStoreFactory;
/** @var BlobStore */
private $blobStore;
/** @var string|null */
private $centralDB;
/**
* @param BlobStoreFactory $blobStoreFactory
* @param BlobStore $blobStore
* @param string|null $centralDB
*/
public function __construct( BlobStoreFactory $blobStoreFactory, BlobStore $blobStore, ?string $centralDB ) {
$this->blobStoreFactory = $blobStoreFactory;
$this->blobStore = $blobStore;
$this->centralDB = $centralDB;
}
/**
* Store a var dump to a BlobStore.
*
* @param AbuseFilterVariableHolder $varsHolder
* @param bool $global
*
* @return string Address of the record
*/
public function storeVarDump( AbuseFilterVariableHolder $varsHolder, $global = false ) {
// Get all variables yet set and compute old and new wikitext if not yet done
// as those are needed for the diff view on top of the abuse log pages
$vars = $varsHolder->dumpAllVars( [ 'old_wikitext', 'new_wikitext' ] );
// Vars is an array with native PHP data types (non-objects) now
$text = FormatJson::encode( $vars );
$dbDomain = $global ? $this->centralDB : false;
$blobStore = $this->blobStoreFactory->newBlobStore( $dbDomain );
$hints = [
BlobStore::DESIGNATION_HINT => 'AbuseFilter',
BlobStore::MODEL_HINT => 'AbuseFilter',
];
return $blobStore->storeBlob( $text, $hints );
}
/**
* Retrieve a var dump from a BlobStore.
*
* @param string $address
*
* @return AbuseFilterVariableHolder
*/
public function loadVarDump( string $address ) : AbuseFilterVariableHolder {
try {
$blob = $this->blobStore->getBlob( $address );
} catch ( BlobAccessException $ex ) {
return new AbuseFilterVariableHolder;
}
$vars = FormatJson::decode( $blob, true );
$obj = AbuseFilterVariableHolder::newFromArray( $vars );
$obj->translateDeprecatedVars();
return $obj;
}
}

View file

@ -14,6 +14,7 @@ use MediaWiki\Extension\AbuseFilter\FilterLookup;
use MediaWiki\Extension\AbuseFilter\GlobalNameUtils;
use MediaWiki\Extension\AbuseFilter\Pager\AbuseFilterExaminePager;
use MediaWiki\Extension\AbuseFilter\VariableGenerator\RCVariableGenerator;
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\Revision\RevisionLookup;
use MediaWiki\Revision\RevisionRecord;
@ -52,12 +53,17 @@ class AbuseFilterViewExamine extends AbuseFilterView {
* @var EditBoxBuilderFactory
*/
private $boxBuilderFactory;
/**
* @var VariablesBlobStore
*/
private $varBlobStore;
/**
* @param RevisionLookup $revisionLookup
* @param AbuseFilterPermissionManager $afPermManager
* @param FilterLookup $filterLookup
* @param EditBoxBuilderFactory $boxBuilderFactory
* @param VariablesBlobStore $varBlobStore
* @param IContextSource $context
* @param LinkRenderer $linkRenderer
* @param string $basePageName
@ -68,6 +74,7 @@ class AbuseFilterViewExamine extends AbuseFilterView {
AbuseFilterPermissionManager $afPermManager,
FilterLookup $filterLookup,
EditBoxBuilderFactory $boxBuilderFactory,
VariablesBlobStore $varBlobStore,
IContextSource $context,
LinkRenderer $linkRenderer,
string $basePageName,
@ -77,6 +84,7 @@ class AbuseFilterViewExamine extends AbuseFilterView {
$this->revisionLookup = $revisionLookup;
$this->filterLookup = $filterLookup;
$this->boxBuilderFactory = $boxBuilderFactory;
$this->varBlobStore = $varBlobStore;
}
/**
@ -249,7 +257,7 @@ class AbuseFilterViewExamine extends AbuseFilterView {
return;
}
}
$vars = AbuseFilter::loadVarDump( $row->afl_var_dump );
$vars = $this->varBlobStore->loadVarDump( $row->afl_var_dump );
$out->addJsConfigVars( [
'wgAbuseFilterVariables' => $vars->dumpAllVars( true ),
'abuseFilterExamine' => [ 'type' => 'log', 'id' => $logid ]

View file

@ -11,6 +11,7 @@ use MediaWiki\Block\DatabaseBlock;
use MediaWiki\Extension\AbuseFilter\AbuseFilterPermissionManager;
use MediaWiki\Extension\AbuseFilter\BlockAutopromoteStore;
use MediaWiki\Extension\AbuseFilter\FilterUser;
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
use MediaWiki\Linker\LinkRenderer;
use MediaWiki\User\UserGroupManager;
use Message;
@ -57,12 +58,17 @@ class AbuseFilterViewRevert extends AbuseFilterView {
* @var FilterUser
*/
private $filterUser;
/**
* @var VariablesBlobStore
*/
private $varBlobStore;
/**
* @param UserGroupManager $userGroupManager
* @param AbuseFilterPermissionManager $afPermManager
* @param BlockAutopromoteStore $blockAutopromoteStore
* @param FilterUser $filterUser
* @param VariablesBlobStore $varBlobStore
* @param IContextSource $context
* @param LinkRenderer $linkRenderer
* @param string $basePageName
@ -73,6 +79,7 @@ class AbuseFilterViewRevert extends AbuseFilterView {
AbuseFilterPermissionManager $afPermManager,
BlockAutopromoteStore $blockAutopromoteStore,
FilterUser $filterUser,
VariablesBlobStore $varBlobStore,
IContextSource $context,
LinkRenderer $linkRenderer,
string $basePageName,
@ -82,6 +89,7 @@ class AbuseFilterViewRevert extends AbuseFilterView {
$this->userGroupsManager = $userGroupManager;
$this->blockAutopromoteStore = $blockAutopromoteStore;
$this->filterUser = $filterUser;
$this->varBlobStore = $varBlobStore;
}
/**
@ -307,7 +315,7 @@ class AbuseFilterViewRevert extends AbuseFilterView {
'actions' => $currentReversibleActions,
'user' => $row->afl_user_text,
'userid' => $row->afl_user,
'vars' => AbuseFilter::loadVarDump( $row->afl_var_dump ),
'vars' => $this->varBlobStore->loadVarDump( $row->afl_var_dump ),
'title' => Title::makeTitle( $row->afl_namespace, $row->afl_title ),
'action' => $row->afl_action,
'timestamp' => $row->afl_timestamp

View file

@ -10,6 +10,7 @@ use MediaWiki\Extension\AbuseFilter\FilterProfiler;
use MediaWiki\Extension\AbuseFilter\FilterStore;
use MediaWiki\Extension\AbuseFilter\FilterUser;
use MediaWiki\Extension\AbuseFilter\Parser\ParserFactory as AfParserFactory;
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
use MediaWiki\Extension\AbuseFilter\View\AbuseFilterView;
use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewDiff;
use MediaWiki\Extension\AbuseFilter\View\AbuseFilterViewEdit;
@ -50,6 +51,7 @@ class SpecialAbuseFilter extends AbuseFilterSpecialPage {
AbuseFilterPermissionManager::SERVICE_NAME,
FilterLookup::SERVICE_NAME,
EditBoxBuilderFactory::SERVICE_NAME,
VariablesBlobStore::SERVICE_NAME,
],
AbuseFilterViewHistory::class => [
AbuseFilterPermissionManager::SERVICE_NAME,
@ -67,6 +69,7 @@ class SpecialAbuseFilter extends AbuseFilterSpecialPage {
AbuseFilterPermissionManager::SERVICE_NAME,
BlockAutopromoteStore::SERVICE_NAME,
FilterUser::SERVICE_NAME,
VariablesBlobStore::SERVICE_NAME,
],
AbuseFilterViewTestBatch::class => [
AbuseFilterPermissionManager::SERVICE_NAME,

View file

@ -6,6 +6,7 @@ use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
use MediaWiki\Extension\AbuseFilter\ConsequencesRegistry;
use MediaWiki\Extension\AbuseFilter\GlobalNameUtils;
use MediaWiki\Extension\AbuseFilter\Pager\AbuseLogPager;
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
use MediaWiki\Extension\AbuseFilter\View\HideAbuseLog;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MediaWikiServices;
@ -78,23 +79,29 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage {
/** @var ConsequencesRegistry */
private $consequencesRegistry;
/** @var VariablesBlobStore */
private $varBlobStore;
/**
* @param LinkBatchFactory $linkBatchFactory
* @param PermissionManager $permissionManager
* @param AbuseFilterPermissionManager $afPermissionManager
* @param ConsequencesRegistry $consequencesRegistry
* @param VariablesBlobStore $varBlobStore
*/
public function __construct(
LinkBatchFactory $linkBatchFactory,
PermissionManager $permissionManager,
AbuseFilterPermissionManager $afPermissionManager,
ConsequencesRegistry $consequencesRegistry
ConsequencesRegistry $consequencesRegistry,
VariablesBlobStore $varBlobStore
) {
parent::__construct( 'AbuseLog', 'abusefilter-log' );
$this->linkBatchFactory = $linkBatchFactory;
$this->permissionManager = $permissionManager;
$this->afPermissionManager = $afPermissionManager;
$this->consequencesRegistry = $consequencesRegistry;
$this->varBlobStore = $varBlobStore;
}
/**
@ -675,7 +682,7 @@ class SpecialAbuseLog extends AbuseFilterSpecialPage {
$output .= Xml::tags( 'p', null, $pager->doFormatRow( $row, false ) );
// Load data
$vars = AbuseFilter::loadVarDump( $row->afl_var_dump );
$vars = $this->varBlobStore->loadVarDump( $row->afl_var_dump );
$out->addJsConfigVars( 'wgAbuseFilterVariables', $vars->dumpAllVars( true ) );
// Diff, if available

View file

@ -2,6 +2,7 @@
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
use MediaWiki\Extension\AbuseFilter\KeywordsManager;
use MediaWiki\Extension\AbuseFilter\VariablesBlobStore;
use MediaWiki\MediaWikiServices;
use Wikimedia\AtEase\AtEase;
use Wikimedia\Rdbms\Database;
@ -43,6 +44,8 @@ class UpdateVarDumps extends LoggedUpdateMaintenance {
private $sleep;
/** @var KeywordsManager */
private $keywordsManager;
/** @var VariablesBlobStore */
private $varBlobStore;
/**
* @inheritDoc
@ -86,6 +89,7 @@ class UpdateVarDumps extends LoggedUpdateMaintenance {
$this->sleep = $this->getOption( 'sleep' );
$this->keywordsManager = AbuseFilterServices::getKeywordsManager();
$this->varBlobStore = AbuseFilterServices::getVariablesBlobStore();
// Faulty rows aren't inserted anymore, hence we can query the replica and update the master.
$this->dbr = wfGetDB( DB_REPLICA );
@ -229,7 +233,7 @@ class UpdateVarDumps extends LoggedUpdateMaintenance {
}
}
$storedID = AbuseFilter::storeVarDump( $vars );
$storedID = $this->varBlobStore->storeVarDump( $vars );
$this->dbw->update(
'abuse_filter_log',
[ 'afl_var_dump' => $storedID ],
@ -333,7 +337,7 @@ class UpdateVarDumps extends LoggedUpdateMaintenance {
if ( !$this->dryRun ) {
$holder = is_array( $stored ) ? AbuseFilterVariableHolder::newFromArray( $stored ) : $stored;
// Note: this will upgrade to the new JSON format, so we use tt:
$newDump = AbuseFilter::storeVarDump( $holder );
$newDump = $this->varBlobStore->storeVarDump( $holder );
$this->dbw->update(
'abuse_filter_log',
[ 'afl_var_dump' => $newDump ],

View file

@ -1347,8 +1347,7 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase {
* @param array $actionParams Details of the action we need to execute to trigger filters
* @param string[] $usedVars The variables effectively computed by filters in $createIds.
* We'll search these in the stored dump.
* @covers AbuseFilter::storeVarDump
* @covers AbuseFilter::loadVarDump
* @covers \MediaWiki\Extension\AbuseFilter\VariablesBlobStore
* @covers AbuseFilterVariableHolder::dumpAllVars
* @dataProvider provideFiltersAndVariables
*/
@ -1366,7 +1365,7 @@ class AbuseFilterConsequencesTest extends MediaWikiTestCase {
[ 'ORDER BY' => 'afl_timestamp DESC' ]
);
$vars = AbuseFilter::loadVarDump( $dumpID )->getVars();
$vars = AbuseFilterServices::getVariablesBlobStore()->loadVarDump( $dumpID )->getVars();
$interestingVars = array_intersect_key( $vars, array_fill_keys( $usedVars, true ) );

View file

@ -1,5 +1,6 @@
<?php
use MediaWiki\Extension\AbuseFilter\AbuseFilterServices;
use MediaWiki\Extension\AbuseFilter\Filter\Filter;
use MediaWiki\Extension\AbuseFilter\FilterLookup;
use MediaWiki\Revision\MutableRevisionRecord;
@ -52,16 +53,16 @@ class AbuseFilterDBTest extends MediaWikiTestCase {
*
* @param array $variables Map of [ name => value ] to build an AbuseFilterVariableHolder with
* @param ?array $expectedValues Null to use $variables
* @covers AbuseFilter::storeVarDump
* @covers AbuseFilter::loadVarDump
* @covers \MediaWiki\Extension\AbuseFilter\VariablesBlobStore
* @covers AbuseFilterVariableHolder::dumpAllVars
* @dataProvider provideVariables
*/
public function testVarDump( array $variables, array $expectedValues = null ) {
$varBlobStore = AbuseFilterServices::getVariablesBlobStore();
$holder = AbuseFilterVariableHolder::newFromArray( $variables );
$insertID = AbuseFilter::storeVarDump( $holder );
$dump = AbuseFilter::loadVarDump( $insertID );
$insertID = $varBlobStore->storeVarDump( $holder );
$dump = $varBlobStore->loadVarDump( $insertID );
$expected = $expectedValues ? AbuseFilterVariableHolder::newFromArray( $expectedValues ) : $holder;
$this->assertEquals( $expected, $dump, 'The var dump is not saved correctly' );
}