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 <gti...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to