From f3f0f6fb30881b9d7fb965c5375689addbdb802e Mon Sep 17 00:00:00 2001 From: Wil Mahan Date: Mon, 27 Sep 2004 21:14:52 +0000 Subject: [PATCH] 1) Use CREATE TEMPORARY TABLE ... LIKE for MySQL >= 4.1 and PostgreSQL (untested, but should fix bug 585). Use a hack for older MySQL versions that doesn't require including a .sql file. 2) Die gracefully when an article has an invalid title or already exists in the database. 3) Detect and report duplicate sections in the test file. --- maintenance/parserTests.php | 84 +++++++++-- maintenance/parserTests.sql | 293 ------------------------------------ maintenance/parserTests.txt | 22 +-- 3 files changed, 80 insertions(+), 319 deletions(-) delete mode 100644 maintenance/parserTests.sql diff --git a/maintenance/parserTests.php b/maintenance/parserTests.php index 06e50bcf0f..9e6b1b8396 100644 --- a/maintenance/parserTests.php +++ b/maintenance/parserTests.php @@ -115,7 +115,7 @@ class ParserTest { if( !isset( $data['article'] ) ) { die( "'endarticle' without 'article' at line $n\n" ); } - $this->addArticle($this->chomp($data['article']), $this->chomp($data['text'])); + $this->addArticle($this->chomp($data['article']), $this->chomp($data['text']), $n); $data = array(); $section = null; continue; @@ -155,6 +155,9 @@ class ParserTest { $section = null; continue; } + if ( isset ($data[$section] ) ) { + die ( "duplicate section '$section' at line $n\n" ); + } $data[$section] = ''; continue; } @@ -282,28 +285,69 @@ class ParserTest { * Currently this will only be done once per run, and any changes to * the db will be visible to later tests in the run. * - * This is ugly, but we need a way to modify the database - * without breaking anything. Currently it isn't possible - * to roll back transactions, which might help with this. - * -- wtm - * * @access private */ function setupDatabase() { static $setupDB = false; - if (!$setupDB && $GLOBALS['wgDBprefix'] === 'parsertest') { + global $wgDBprefix; + + # Make sure we don't mess with the live DB + if (!$setupDB && $wgDBprefix === 'parsertest') { $db =& wfGetDB( DB_MASTER ); - if (0) { - # XXX CREATE TABLE ... LIKE requires MySQL 4.1 - $tables = array('cur', 'interwiki', 'brokenlinks', 'recentchanges'); + + # List of temporary tables to create, without prefix + # Some of these probably aren't necessary + $tables = array('user', 'cur', 'old', 'links', + 'brokenlinks', 'imagelinks', 'categorylinks', + 'linkscc', 'site_stats', 'hitcounter', + 'ipblocks', 'image', 'oldimage', + 'recentchanges', + 'watchlist', 'math', 'searchindex', + 'interwiki', 'querycache', + 'objectcache', 'blobs', 'validate' + ); + + # List of tables whose contents we need to copy + $copy_tables = array('interwiki'); + + if (!(strcmp($db->getServerVersion(), '4.1') < 0 and stristr($db->getSoftwareLink(), 'MySQL'))) { + # Database that supports CREATE TABLE ... LIKE foreach ($tables as $tbl) { - $db->query('CREATE TEMPORARY TABLE ' . $GLOBALS['wgDBprefix'] . "$tbl LIKE $tbl"); + $db->query("CREATE TEMPORARY TABLE $wgDBprefix$tbl LIKE $tbl"); } } else { - # HACK, sorry - dbsource( 'maintenance/parserTests.sql', $db ); + # Hack for MySQL versions < 4.1, which don't support + # "CREATE TABLE ... LIKE". Note that + # "CREATE TEMPORARY TABLE ... SELECT * FROM ... LIMIT 0" + # would not create the indexes we need.... + foreach ($tables as $tbl) { + $res = $db->query("SHOW CREATE TABLE $tbl"); + $row = $db->fetchRow($res); + $create = $row[1]; + $create_tmp = preg_replace('/CREATE TABLE `(.*?)`/', 'CREATE TEMPORARY TABLE `' + . $wgDBprefix . '\\1`', $create); + if ($create === $create_tmp) { + # Couldn't do replacement + die("could not create temporary table $tbl"); + } + $db->query($create_tmp); + } + + } + + foreach ($copy_tables as $tbl) { + $db->query("INSERT INTO $wgDBprefix$tbl SELECT * FROM $tbl"); } + + # Hack: insert a few Wikipedia in-project interwiki prefixes, + # for testing inter-language links + $db->query("INSERT INTO ${wgDBprefix}interwiki + (iw_prefix,iw_url,iw_local) VALUES + ('zh','http://zh.wikipedia.org/wiki/$1',1), + ('es','http://es.wikipedia.org/wiki/$1',1), + ('fr','http://fr.wikipedia.org/wiki/$1',1)"); + $setupDB = true; } } @@ -431,14 +475,22 @@ class ParserTest { * Insert a temporary test article * @param $name string the title, including any prefix * @param $text string the article text + * @param $line int the input line number, for reporting errors * @static * @access private */ - function addArticle($name, $text) { - # TODO: check if article exists and die gracefully - # if we are trying to insert a duplicate + function addArticle($name, $text, $line) { $this->setupGlobals(); $title = Title::newFromText( $name ); + if ( is_null($title) ) { + die( "invalid title at line $line\n" ); + } + + $aid = $title->getArticleID( GAID_FOR_UPDATE ); + if ($aid != 0) { + die( "duplicate article at line $line\n" ); + } + $art = new Article($title); $art->insertNewArticle($text, '', false, false ); $this->teardownGlobals(); diff --git a/maintenance/parserTests.sql b/maintenance/parserTests.sql deleted file mode 100644 index 26e22af67a..0000000000 --- a/maintenance/parserTests.sql +++ /dev/null @@ -1,293 +0,0 @@ --- HACK: this should go away when there is a better way - -CREATE TEMPORARY TABLE parsertestuser ( - user_id int(5) unsigned NOT NULL auto_increment, - user_name varchar(255) binary NOT NULL default '', - user_real_name varchar(255) binary NOT NULL default '', - user_password tinyblob NOT NULL default '', - user_newpassword tinyblob NOT NULL default '', - user_email tinytext NOT NULL default '', - user_options blob NOT NULL default '', - user_touched char(14) binary NOT NULL default '', - PRIMARY KEY user_id (user_id), - INDEX user_name (user_name(10)) -); - -CREATE TEMPORARY TABLE parsertestcur ( - cur_id int(8) unsigned NOT NULL auto_increment, - cur_namespace tinyint(2) unsigned NOT NULL default '0', - cur_title varchar(255) binary NOT NULL default '', - cur_text mediumtext NOT NULL default '', - cur_comment tinyblob NOT NULL default '', - cur_user int(5) unsigned NOT NULL default '0', - cur_user_text varchar(255) binary NOT NULL default '', - cur_timestamp char(14) binary NOT NULL default '', - cur_restrictions tinyblob NOT NULL default '', - cur_counter bigint(20) unsigned NOT NULL default '0', - cur_is_redirect tinyint(1) unsigned NOT NULL default '0', - cur_minor_edit tinyint(1) unsigned NOT NULL default '0', - cur_is_new tinyint(1) unsigned NOT NULL default '0', - cur_random real unsigned NOT NULL, - cur_touched char(14) binary NOT NULL default '', - inverse_timestamp char(14) binary NOT NULL default '', - PRIMARY KEY cur_id (cur_id), - UNIQUE INDEX name_title (cur_namespace,cur_title), - - -- Is this one necessary? - INDEX cur_title (cur_title(20)), - - INDEX cur_timestamp (cur_timestamp), - INDEX (cur_random), - INDEX name_title_timestamp (cur_namespace,cur_title,inverse_timestamp), - INDEX user_timestamp (cur_user,inverse_timestamp), - INDEX usertext_timestamp (cur_user_text,inverse_timestamp), - INDEX namespace_redirect_timestamp(cur_namespace,cur_is_redirect,cur_timestamp) -); - -CREATE TEMPORARY TABLE parsertestold ( - old_id int(8) unsigned NOT NULL auto_increment, - old_namespace tinyint(2) unsigned NOT NULL default '0', - old_title varchar(255) binary NOT NULL default '', - old_text mediumtext NOT NULL default '', - old_comment tinyblob NOT NULL default '', - old_user int(5) unsigned NOT NULL default '0', - old_user_text varchar(255) binary NOT NULL, - old_timestamp char(14) binary NOT NULL default '', - old_minor_edit tinyint(1) NOT NULL default '0', - old_flags tinyblob NOT NULL default '', - inverse_timestamp char(14) binary NOT NULL default '', - - PRIMARY KEY old_id (old_id), - INDEX old_timestamp (old_timestamp), - INDEX name_title_timestamp (old_namespace,old_title,inverse_timestamp), - INDEX user_timestamp (old_user,inverse_timestamp), - INDEX usertext_timestamp (old_user_text,inverse_timestamp) -); - -CREATE TEMPORARY TABLE parsertestlinks ( - l_from int(8) unsigned NOT NULL default '0', - l_to int(8) unsigned NOT NULL default '0', - UNIQUE KEY l_from(l_from,l_to), - KEY (l_to) -); - -CREATE TEMPORARY TABLE parsertestbrokenlinks ( - bl_from int(8) unsigned NOT NULL default '0', - bl_to varchar(255) binary NOT NULL default '', - UNIQUE KEY bl_from(bl_from,bl_to), - KEY (bl_to) -); - -CREATE TEMPORARY TABLE parsertestimagelinks ( - il_from int(8) unsigned NOT NULL default '0', - il_to varchar(255) binary NOT NULL default '', - UNIQUE KEY il_from(il_from,il_to), - KEY (il_to) -); - -CREATE TEMPORARY TABLE parsertestcategorylinks ( - cl_from int(8) unsigned NOT NULL default '0', - cl_to varchar(255) binary NOT NULL default '', - cl_sortkey varchar(255) binary NOT NULL default '', - cl_timestamp timestamp NOT NULL, - UNIQUE KEY cl_from(cl_from,cl_to), - KEY cl_sortkey(cl_to,cl_sortkey(128)), - KEY cl_timestamp(cl_to,cl_timestamp) -); - --- --- Stores (possibly gzipped) serialized objects with --- cache arrays to reduce database load slurping up --- from links and brokenlinks. --- -CREATE TEMPORARY TABLE parsertestlinkscc ( - lcc_pageid INT UNSIGNED NOT NULL UNIQUE KEY, - lcc_cacheobj MEDIUMBLOB NOT NULL -); - -CREATE TEMPORARY TABLE parsertestsite_stats ( - ss_row_id int(8) unsigned NOT NULL, - ss_total_views bigint(20) unsigned default '0', - ss_total_edits bigint(20) unsigned default '0', - ss_good_articles bigint(20) unsigned default '0', - UNIQUE KEY ss_row_id (ss_row_id) -); - -CREATE TEMPORARY TABLE parsertesthitcounter ( - hc_id INTEGER UNSIGNED NOT NULL -) TYPE=HEAP MAX_ROWS=25000; - -CREATE TEMPORARY TABLE parsertestipblocks ( - ipb_id int(8) NOT NULL auto_increment, - ipb_address varchar(40) binary NOT NULL default '', - ipb_user int(8) unsigned NOT NULL default '0', - ipb_by int(8) unsigned NOT NULL default '0', - ipb_reason tinyblob NOT NULL default '', - ipb_timestamp char(14) binary NOT NULL default '', - ipb_auto tinyint(1) NOT NULL default '0', - ipb_expiry char(14) binary NOT NULL default '', - - PRIMARY KEY ipb_id (ipb_id), - INDEX ipb_address (ipb_address), - INDEX ipb_user (ipb_user) -); - -CREATE TEMPORARY TABLE parsertestimage ( - img_name varchar(255) binary NOT NULL default '', - img_size int(8) unsigned NOT NULL default '0', - img_description tinyblob NOT NULL default '', - img_user int(5) unsigned NOT NULL default '0', - img_user_text varchar(255) binary NOT NULL default '', - img_timestamp char(14) binary NOT NULL default '', - PRIMARY KEY img_name (img_name), - INDEX img_size (img_size), - INDEX img_timestamp (img_timestamp) -); - -CREATE TEMPORARY TABLE parsertestoldimage ( - oi_name varchar(255) binary NOT NULL default '', - oi_archive_name varchar(255) binary NOT NULL default '', - oi_size int(8) unsigned NOT NULL default 0, - oi_description tinyblob NOT NULL default '', - oi_user int(5) unsigned NOT NULL default '0', - oi_user_text varchar(255) binary NOT NULL default '', - oi_timestamp char(14) binary NOT NULL default '', - INDEX oi_name (oi_name(10)) -); - -CREATE TEMPORARY TABLE parsertestrecentchanges ( - rc_id int(8) NOT NULL auto_increment, - rc_timestamp varchar(14) binary NOT NULL default '', - rc_cur_time varchar(14) binary NOT NULL default '', - rc_user int(10) unsigned NOT NULL default '0', - rc_user_text varchar(255) binary NOT NULL default '', - rc_namespace tinyint(3) NOT NULL default '0', - rc_title varchar(255) binary NOT NULL default '', - rc_comment varchar(255) binary NOT NULL default '', - rc_minor tinyint(3) unsigned NOT NULL default '0', - rc_bot tinyint(3) unsigned NOT NULL default '0', - rc_new tinyint(3) unsigned NOT NULL default '0', - rc_cur_id int(10) unsigned NOT NULL default '0', - rc_this_oldid int(10) unsigned NOT NULL default '0', - rc_last_oldid int(10) unsigned NOT NULL default '0', - rc_type tinyint(3) unsigned NOT NULL default '0', - rc_moved_to_ns tinyint(3) unsigned NOT NULL default '0', - rc_moved_to_title varchar(255) binary NOT NULL default '', - rc_patrolled tinyint(3) unsigned NOT NULL default '0', - rc_ip char(15) NOT NULL default '', - - PRIMARY KEY rc_id (rc_id), - INDEX rc_timestamp (rc_timestamp), - INDEX rc_namespace_title (rc_namespace, rc_title), - INDEX rc_cur_id (rc_cur_id), - INDEX new_name_timestamp(rc_new,rc_namespace,rc_timestamp), - INDEX rc_ip (rc_ip) -); - -CREATE TEMPORARY TABLE parsertestwatchlist ( - wl_user int(5) unsigned NOT NULL, - wl_namespace tinyint(2) unsigned NOT NULL default '0', - wl_title varchar(255) binary NOT NULL default '', - UNIQUE KEY (wl_user, wl_namespace, wl_title), - KEY namespace_title (wl_namespace,wl_title) -); - -CREATE TEMPORARY TABLE parsertestmath ( - math_inputhash varchar(16) NOT NULL, - math_outputhash varchar(16) NOT NULL, - math_html_conservativeness tinyint(1) NOT NULL, - math_html text, - math_mathml text, - UNIQUE KEY math_inputhash (math_inputhash) -); - - --- Table searchindex must be MyISAM for fulltext support - -CREATE TEMPORARY TABLE parsertestsearchindex ( - si_page int(8) unsigned NOT NULL, - si_title varchar(255) NOT NULL default '', - si_text mediumtext NOT NULL default '', - UNIQUE KEY (si_page), - FULLTEXT si_title (si_title), - FULLTEXT si_text (si_text) - -) TYPE=MyISAM; - -CREATE TEMPORARY TABLE parsertestinterwiki ( - iw_prefix char(32) NOT NULL, - iw_url char(127) NOT NULL, - iw_local BOOL NOT NULL, - UNIQUE KEY iw_prefix (iw_prefix) -); - --- Used for caching expensive grouped queries -CREATE TEMPORARY TABLE parsertestquerycache ( - qc_type char(32) NOT NULL, - qc_value int(5) unsigned NOT NULL default '0', - qc_namespace tinyint(2) unsigned NOT NULL default '0', - qc_title char(255) binary NOT NULL default '', - KEY (qc_type,qc_value) -); - --- For a few generic cache operations if not using Memcached -CREATE TEMPORARY TABLE parsertestobjectcache ( - keyname char(255) binary not null default '', - value mediumblob, - exptime datetime, - unique key (keyname), - key (exptime) -); - --- For storing revision text -CREATE TEMPORARY TABLE parsertestblobs ( - blob_index char(255) binary NOT NULL default '', - blob_data longblob NOT NULL default '', - UNIQUE key blob_index (blob_index) -); - --- For article validation - -CREATE TEMPORARY TABLE `parsertestvalidate` ( - `val_user` int(11) NOT NULL default '0', - `val_title` varchar(255) binary NOT NULL default '', - `val_timestamp` varchar(14) binary NOT NULL default '', - `val_type` int(10) unsigned NOT NULL default '0', - `val_value` int(11) default '0', - `val_comment` varchar(255) NOT NULL default '', - KEY `val_user` (`val_user`,`val_title`,`val_timestamp`) -); - - -CREATE TEMPORARY TABLE parsertestlogging ( - -- Symbolic keys for the general log type and the action type - -- within the log. The output format will be controlled by the - -- action field, but only the type controls categorization. - log_type char(10) NOT NULL default '', - log_action char(10) NOT NULL default '', - - -- Timestamp. Duh. - log_timestamp char(14) NOT NULL default '19700101000000', - - -- The user who performed this action; key to user_id - log_user int unsigned NOT NULL default 0, - - -- Key to the page affected. Where a user is the target, - -- this will point to the user page. - log_namespace tinyint unsigned NOT NULL default 0, - log_title varchar(255) NOT NULL default '', - - -- Freeform text. Interpreted as edit history comments. - log_comment varchar(255) NOT NULL default '', - - KEY type_time (log_type, log_timestamp), - KEY user_time (log_user, log_timestamp), - KEY page_time (log_namespace, log_title, log_timestamp) -); - -INSERT INTO parsertestinterwiki (iw_prefix,iw_url,iw_local) VALUES - ('MeatBall','http://www.usemod.com/cgi-bin/mb.pl?$1',0), - ('es','http://es.wikipedia.org/wiki/$1',1), - ('fr','http://fr.wikipedia.org/wiki/$1',1), - ('zh','http://zh.wikipedia.org/wiki/$1',1); - diff --git a/maintenance/parserTests.txt b/maintenance/parserTests.txt index 68d34a5bbd..abe4107be6 100644 --- a/maintenance/parserTests.txt +++ b/maintenance/parserTests.txt @@ -30,7 +30,6 @@ Main Page blah blah !! endarticle - ### ### Basic tests ### @@ -40,6 +39,7 @@ Blank input !! result !! end + !! test Simple paragraph !! input @@ -296,7 +296,7 @@ Definition list with wikilink containing colon !! input ; [[Wikipedia:FAQ]]: The least-read page on Wikipedia !! result -
Wikipedia:FAQ
The least-read page on Wikipedia +
Wikipedia:FAQ
The least-read page on Wikipedia
!! end @@ -322,6 +322,16 @@ Malformed definition list with colon !! end +!! test +Definition lists: colon in external link text +!! input +; [http://www.wikipedia2.org/ Wikipedia : The Next Generation]: OK, I made that up +!! result +
Wikipedia : The Next Generation (http://www.wikipedia2.org/)
OK, I made that up +
+ +!! end + ### ### External links @@ -826,14 +836,6 @@ Inline interwiki link

!! end -### -### Images -### - -!! test -[[ - - ## ## XHTML tidiness ### -- 2.20.1