Gergő Tisza has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/394728 )
Change subject: Add maintenance script for populating DB with test data
......................................................................
Add maintenance script for populating DB with test data
Change-Id: Ia9e81b2021fd03e1dc78b8d1083773eb4c34bf51
---
A maintenance/populateWithTestData.php
1 file changed, 192 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ReadingLists
refs/changes/28/394728/1
diff --git a/maintenance/populateWithTestData.php
b/maintenance/populateWithTestData.php
new file mode 100644
index 0000000..70874ae
--- /dev/null
+++ b/maintenance/populateWithTestData.php
@@ -0,0 +1,192 @@
+<?php
+
+namespace MediaWiki\Extensions\ReadingLists\Maintenance;
+
+use Maintenance;
+use MediaWiki\Extensions\ReadingLists\ReadingListRepository;
+use MediaWiki\Extensions\ReadingLists\ReadingListRepositoryException;
+use MediaWiki\Extensions\ReadingLists\Utils;
+use MediaWiki\MediaWikiServices;
+use Wikimedia\Rdbms\DBConnRef;
+use Wikimedia\Rdbms\LBFactory;
+
+require_once getenv( 'MW_INSTALL_PATH' ) !== false
+ ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php'
+ : __DIR__ . '/../../../maintenance/Maintenance.php';
+
+/**
+ * Fill the database with test data, or remove it.
+ */
+class PopulateWithTestData extends Maintenance {
+
+ /** @var LBFactory */
+ private $loadBalancerFactory;
+
+ /** @var DBConnRef */
+ private $dbw;
+
+ /** @var DBConnRef */
+ private $dbr;
+
+ public function __construct() {
+ parent::__construct();
+ $this->addDescription( 'Fill the database with test data, or
remove it.' );
+ $this->addOption( 'users', 'Number of users', false, true );
+ $this->addOption( 'lists', 'Lists per user (number or stats
distribution)', false, true );
+ $this->addOption( 'entries', 'Entries per list (number or stats
distribution)', false, true );
+ $this->addOption( 'cleanup', 'Delete lists which look like test
data' );
+ if ( !extension_loaded( 'stats' ) ) {
+ $this->error( 'Requires the stats PHP extension', 1 );
+ }
+ }
+
+ private function setupServices() {
+ // Can't do this in the constructor, initialization not done
yet.
+ $services = MediaWikiServices::getInstance();
+ $this->loadBalancerFactory =
$services->getDBLoadBalancerFactory();
+ $this->dbw = Utils::getDB( DB_MASTER, $services );
+ $this->dbr = Utils::getDB( DB_REPLICA, $services );
+ }
+
+ /**
+ * @inheritDoc
+ */
+ public function execute() {
+ $this->setupServices();
+ $this->assertOptions();
+ if ( $this->getOption( 'cleanup' ) ) {
+ $this->cleanupTestData();
+ return;
+ }
+
+ $projects = $this->dbw->selectFieldValues(
'reading_list_project', 'rlp_id' );
+ if ( !$projects ) {
+ $this->error( 'No projects! Please set up some', 1 );
+ }
+ $totalLists = $totalEntries = 0;
+ stats_rand_setall( mt_rand(), mt_rand() );
+ $users = $this->getOption( 'users' );
+ for ( $i = 0; $i < $users; $i++ ) {
+ // The test data is for performance testing so we don't
care whether the user exists.
+ $centralId = 1000 + $i;
+ $repository = new ReadingListRepository( $centralId,
$this->dbw, $this->dbr,
+ $this->loadBalancerFactory );
+ try {
+ $repository->setupForUser();
+ $i++;
+ // HACK mark default list so it will be deleted
together with the rest
+ $this->dbw->update(
+ 'reading_list',
+ [ 'rl_description' => __FILE__ ],
+ [
+ 'rl_user_id' => $centralId,
+ 'rl_is_default' => 1,
+ ]
+ );
+ } catch ( ReadingListRepositoryException $e ) {}
+ $lists = $this->getRandomValueFromDistribution(
$this->getOption( 'lists' ) );
+ for ( $j = 0; $j < $lists; $j++, $totalLists++ ) {
+ $listId = $repository->addList( "test_$j",
__FILE__ );
+ $entries =
$this->getRandomValueFromDistribution( $this->getOption( 'entries' ) );
+ $rows = [];
+ for ( $k = 0; $k < $entries; $k++,
$totalEntries++ ) {
+ $project = $projects[array_rand(
$projects )];
+ // Calling addListEntry for each row
separately would be a bit slow.
+ $rows[] = [
+ 'rle_rl_id' => $listId,
+ 'rle_user_id' => $centralId,
+ 'rle_rlp_id' => $project,
+ 'rle_title' => "Test_$k",
+ ];
+ }
+ $this->dbw->insert(
+ 'reading_list_entry',
+ $rows
+ );
+ }
+ $this->output( '.' );
+ }
+ $this->output( "\nAdded $totalLists lists and $totalEntries
entries for $users users\n" );
+ }
+
+ private function cleanupTestData() {
+ $services = MediaWikiServices::getInstance();
+ $dbw = Utils::getDB( DB_MASTER, $services );
+ $ids = $dbw->selectFieldValues(
+ 'reading_list',
+ 'rl_id',
+ [ 'rl_description' => __FILE__ ]
+ );
+ if ( !$ids ) {
+ $this->output( "Noting to clean up\n" );
+ return;
+ }
+ $dbw->delete(
+ 'reading_list_entry',
+ [ 'rle_rl_id' => $ids ]
+ );
+ $entries = $dbw->affectedRows();
+ $dbw->delete(
+ 'reading_list',
+ [ 'rl_description' => __FILE__ ]
+ );
+ $lists = $dbw->affectedRows();
+ $this->output( "Deleted $lists lists and $entries entries\n" );
+ }
+
+ /**
+ * Get a random value according to some distribution. The parameter is
either a constant
+ * (in which case it will be returned) or a distribution descriptor in
the form of
+ * '<dist>,<param1>,<param2>,...' (no spaces) where <dist> refers to
one of the stats_rand_gen_*
+ * methods (e.g. 'exponential,1' for an exponential distribution with
λ=1, or 'normal,0,1' for
+ * a normal distribution with µ=0, ρ=1).
+ * The result is normalized to be a nonnegative integer.
+ * @param string $distribution
+ * @return int
+ */
+ private function getRandomValueFromDistribution( $distribution ) {
+ $params = explode( ',', $distribution );
+ $type = trim( array_shift( $params ) );
+ if ( is_numeric( $type ) ) {
+ return (int)$type;
+ }
+ $function = "stats_rand_gen_$type";
+ if (
+ !preg_match( '/[a-z_]+/', $type )
+ || !function_exists( $function )
+ ) {
+ $this->error( "invalid distribution: $distribution
(could not parse '$type')" );
+ }
+ $params = array_map( function ( $param ) use ( $distribution ) {
+ if ( !is_numeric( $param ) ) {
+ $this->error( "invalid distribution:
$distribution (could not parse '$param')" );
+ }
+ return (float)$param;
+ }, $params );
+ return max( (int)call_user_func_array( $function, $params ), 0
);
+ }
+
+ private function assertOptions() {
+ if ( $this->hasOption( 'cleanup' ) ) {
+ if (
+ $this->hasOption( 'users' )
+ || $this->hasOption( 'lists' )
+ || $this->hasOption( 'entries' )
+ ) {
+ $this->error( "'cleanup' cannot be used
together with other options", 1 );
+ }
+ } else {
+ if (
+ !$this->hasOption( 'users' )
+ || !$this->hasOption( 'lists' )
+ || !$this->hasOption( 'entries' )
+ ) {
+ $this->error( "'users', 'lists' and 'entries'
are required in non-cleanup mode", 1 );
+ }
+ }
+ }
+
+}
+
+$maintClass = PopulateWithTestData::class;
+require_once RUN_MAINTENANCE_IF_MAIN;
--
To view, visit https://gerrit.wikimedia.org/r/394728
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia9e81b2021fd03e1dc78b8d1083773eb4c34bf51
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ReadingLists
Gerrit-Branch: master
Gerrit-Owner: Gergő Tisza <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits