Index: branches/querypage-work2/phase3/maintenance/helloWorld.php |
— | — | @@ -1,59 +0,0 @@ |
2 | | -<<<<<<< .working |
3 | | -<?php |
4 | | - |
5 | | -/** |
6 | | - * To the extent possible under law, I, Mark Hershberger, have waived all copyright and |
7 | | - * related or neighboring rights to Hello World. This work is published from United States. |
8 | | - * @copyright CC0 http://creativecommons.org/publicdomain/zero/1.0/ |
9 | | - * @author Mark A. Hershberger <mah@everybody.org> |
10 | | - * @ingroup Maintenance |
11 | | - */ |
12 | | - |
13 | | -require_once( dirname( __FILE__ ) . "/Maintenance.php" ); |
14 | | - |
15 | | -class CommandLineInstaller extends Maintenance { |
16 | | - |
17 | | - public function __construct() { |
18 | | - parent::__construct(); |
19 | | - |
20 | | - $this->addOption( 'name', 'Who to say Hello to', false, true); |
21 | | - } |
22 | | - |
23 | | - public function execute() { |
24 | | - $name = $this->getOption( 'name', 'World' ); |
25 | | - echo "Hello, $name!\n"; |
26 | | - } |
27 | | -} |
28 | | - |
29 | | -wfRunMaintenance( "CommandLineInstaller" ); |
30 | | - |
31 | | -======= |
32 | | -<?php |
33 | | -/** |
34 | | - * To the extent possible under law, I, Mark Hershberger, have waived all copyright and |
35 | | - * related or neighboring rights to Hello World. This work is published from United States. |
36 | | - * |
37 | | - * @file |
38 | | - * @ingroup Maintenance |
39 | | - * @copyright CC0 http://creativecommons.org/publicdomain/zero/1.0/ |
40 | | - * @author Mark A. Hershberger <mah@everybody.org> |
41 | | - */ |
42 | | - |
43 | | -require_once( dirname( __FILE__ ) . '/Maintenance.php' ); |
44 | | - |
45 | | -class CommandLineInstaller extends Maintenance { |
46 | | - |
47 | | - public function __construct() { |
48 | | - parent::__construct(); |
49 | | - |
50 | | - $this->addOption( 'name', 'Who to say Hello to', false, true ); |
51 | | - } |
52 | | - |
53 | | - public function execute() { |
54 | | - $name = $this->getOption( 'name', 'World' ); |
55 | | - echo "Hello, $name!\n"; |
56 | | - } |
57 | | -} |
58 | | - |
59 | | -wfRunMaintenance( 'CommandLineInstaller' ); |
60 | | ->>>>>>> .merge-right.r72357 |
Index: branches/querypage-work2/phase3/maintenance/upgrade1_5.php |
— | — | @@ -344,7 +344,7 @@ |
345 | 345 | __METHOD__ ); |
346 | 346 | |
347 | 347 | $add = array(); |
348 | | - while ( $row = $this->dbr->fetchObject( $result ) ) { |
| 348 | + foreach ( $result as $row ) { |
349 | 349 | $copy = array(); |
350 | 350 | foreach ( $fields as $field => $source ) { |
351 | 351 | if ( $source === MW_UPGRADE_COPY ) { |
— | — | @@ -455,7 +455,7 @@ |
456 | 456 | FROM $cur |
457 | 457 | ORDER BY cur_id", __METHOD__ ); |
458 | 458 | $add = array(); |
459 | | - while ( $row = $this->dbr->fetchObject( $result ) ) { |
| 459 | + foreach ( $result as $row ) { |
460 | 460 | $add[] = array( |
461 | 461 | 'old_namespace' => $row->cur_namespace, |
462 | 462 | 'old_title' => $row->cur_title, |
— | — | @@ -488,7 +488,7 @@ |
489 | 489 | __METHOD__ ); |
490 | 490 | |
491 | 491 | $add = array(); |
492 | | - while ( $row = $this->dbr->fetchObject( $result ) ) { |
| 492 | + foreach ( $result as $row ) { |
493 | 493 | $add[] = array( |
494 | 494 | 'rev_id' => $row->old_id, |
495 | 495 | 'rev_page' => $row->cur_id, |
— | — | @@ -516,7 +516,7 @@ |
517 | 517 | WHERE cur_id=rev_page AND rev_timestamp=cur_timestamp AND rev_id > {$maxold} |
518 | 518 | ORDER BY cur_id", __METHOD__ ); |
519 | 519 | $add = array(); |
520 | | - while ( $row = $this->dbr->fetchObject( $result ) ) { |
| 520 | + foreach ( $result as $row ) { |
521 | 521 | $add[] = array( |
522 | 522 | 'page_id' => $row->cur_id, |
523 | 523 | 'page_namespace' => $row->cur_namespace, |
— | — | @@ -578,7 +578,7 @@ |
579 | 579 | FROM $links, $cur |
580 | 580 | WHERE l_to=cur_id", __METHOD__ ); |
581 | 581 | $add = array(); |
582 | | - while ( $row = $this->dbr->fetchObject( $result ) ) { |
| 582 | + foreach ( $result as $row ) { |
583 | 583 | $add[] = array( |
584 | 584 | 'pl_from' => $row->l_from, |
585 | 585 | 'pl_namespace' => $row->cur_namespace, |
— | — | @@ -598,7 +598,7 @@ |
599 | 599 | "SELECT bl_from, bl_to FROM $brokenlinks", |
600 | 600 | __METHOD__ ); |
601 | 601 | $add = array(); |
602 | | - while ( $row = $this->dbr->fetchObject( $result ) ) { |
| 602 | + foreach ( $result as $row ) { |
603 | 603 | $pagename = $this->conv( $row->bl_to ); |
604 | 604 | $title = Title::newFromText( $pagename ); |
605 | 605 | if ( is_null( $title ) ) { |
— | — | @@ -905,7 +905,7 @@ |
906 | 906 | __METHOD__ ); |
907 | 907 | |
908 | 908 | $add = array(); |
909 | | - while ( $row = $this->dbr->fetchObject( $result ) ) { |
| 909 | + foreach ( $result as $row ) { |
910 | 910 | $add[] = array( |
911 | 911 | 'wl_user' => $row->wl_user, |
912 | 912 | 'wl_namespace' => MWNamespace::getSubject( $row->wl_namespace ), |
— | — | @@ -1214,7 +1214,7 @@ |
1215 | 1215 | echo "Found $n titles with duplicate entries.\n"; |
1216 | 1216 | if ( $n > 0 ) { |
1217 | 1217 | echo "Correcting...\n"; |
1218 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
| 1218 | + foreach ( $res as $row ) { |
1219 | 1219 | $ns = intval( $row->cur_namespace ); |
1220 | 1220 | $title = $dbw->addQuotes( $row->cur_title ); |
1221 | 1221 | |
Index: branches/querypage-work2/phase3/maintenance/postgres/compare_schemas.pl |
— | — | @@ -273,7 +273,7 @@ |
274 | 274 | ## Simple text-only strings: |
275 | 275 | ar_flags tinyblob TEXT |
276 | 276 | cl_collation varbinary(32) TEXT |
277 | | -cl_sortkey varbinary(255) TEXT |
| 277 | +cl_sortkey varbinary(230) TEXT |
278 | 278 | ct_params blob TEXT |
279 | 279 | fa_minor_mime varbinary(100) TEXT |
280 | 280 | fa_storage_group varbinary(16) TEXT # Just 'deleted' for now, should stay plain text |
Index: branches/querypage-work2/phase3/maintenance/Maintenance.php |
— | — | @@ -9,11 +9,6 @@ |
10 | 10 | define( 'DO_MAINTENANCE', dirname( __FILE__ ) . '/doMaintenance.php' ); |
11 | 11 | $maintClass = false; |
12 | 12 | |
13 | | -function wfRunMaintenance( $class ) { |
14 | | - $maintClass = $class; |
15 | | - require_once( DO_MAINTENANCE ); |
16 | | -} |
17 | | - |
18 | 13 | // Make sure we're on PHP5 or better |
19 | 14 | if ( version_compare( PHP_VERSION, '5.1.0' ) < 0 ) { |
20 | 15 | die ( "Sorry! This version of MediaWiki requires PHP 5.1.x; you are running " . |
— | — | @@ -351,6 +346,7 @@ |
352 | 347 | $this->addOption( 'conf', 'Location of LocalSettings.php, if not default', false, true ); |
353 | 348 | $this->addOption( 'wiki', 'For specifying the wiki ID', false, true ); |
354 | 349 | $this->addOption( 'globals', 'Output globals at the end of processing for debugging' ); |
| 350 | + $this->addOption( 'memory-limit', 'Set a specific memory limit for the script, "max" for no limit or "default" to avoid changing it' ); |
355 | 351 | // If we support a DB, show the options |
356 | 352 | if ( $this->getDbType() > 0 ) { |
357 | 353 | $this->addOption( 'dbuser', 'The DB user to use for this script', false, true ); |
— | — | @@ -430,9 +426,12 @@ |
431 | 427 | // command-line mode is on, regardless of PHP version. |
432 | 428 | } |
433 | 429 | |
| 430 | + $this->loadParamsAndArgs(); |
| 431 | + $this->maybeHelp(); |
| 432 | + |
434 | 433 | # Set the memory limit |
435 | 434 | # Note we need to set it again later in cache LocalSettings changed it |
436 | | - ini_set( 'memory_limit', $this->memoryLimit() ); |
| 435 | + $this->adjustMemoryLimit(); |
437 | 436 | |
438 | 437 | # Set max execution time to 0 (no limit). PHP.net says that |
439 | 438 | # "When running PHP from the command line the default setting is 0." |
— | — | @@ -453,21 +452,37 @@ |
454 | 453 | # Turn off output buffering if it's on |
455 | 454 | @ob_end_flush(); |
456 | 455 | |
457 | | - $this->loadParamsAndArgs(); |
458 | | - $this->maybeHelp(); |
459 | 456 | $this->validateParamsAndArgs(); |
460 | 457 | } |
461 | 458 | |
462 | 459 | /** |
463 | 460 | * Normally we disable the memory_limit when running admin scripts. |
464 | 461 | * Some scripts may wish to actually set a limit, however, to avoid |
465 | | - * blowing up unexpectedly. |
| 462 | + * blowing up unexpectedly. We also support a --memory-limit option, |
| 463 | + * to allow sysadmins to explicitly set one if they'd prefer to override |
| 464 | + * defaults (or for people using Suhosin which yells at you for trying |
| 465 | + * to disable the limits) |
466 | 466 | */ |
467 | 467 | public function memoryLimit() { |
468 | | - return -1; |
| 468 | + $limit = $this->getOption( 'memory-limit', 'max' ); |
| 469 | + $limit = trim( $limit, "\" '" ); // trim quotes in case someone misunderstood |
| 470 | + return $limit; |
469 | 471 | } |
470 | 472 | |
471 | 473 | /** |
| 474 | + * Adjusts PHP's memory limit to better suit our needs, if needed. |
| 475 | + */ |
| 476 | + protected function adjustMemoryLimit() { |
| 477 | + $limit = $this->memoryLimit(); |
| 478 | + if ( $limit == 'max' ) { |
| 479 | + $limit = -1; // no memory limit |
| 480 | + } |
| 481 | + if ( $limit != 'default' ) { |
| 482 | + ini_set( 'memory_limit', $limit ); |
| 483 | + } |
| 484 | + } |
| 485 | + |
| 486 | + /** |
472 | 487 | * Clear all params and arguments. |
473 | 488 | */ |
474 | 489 | public function clearParamsAndArgs() { |
— | — | @@ -702,7 +717,7 @@ |
703 | 718 | |
704 | 719 | $wgShowSQLErrors = true; |
705 | 720 | @set_time_limit( 0 ); |
706 | | - ini_set( 'memory_limit', $this->memoryLimit() ); |
| 721 | + $this->adjustMemoryLimit(); |
707 | 722 | |
708 | 723 | $wgProfiling = false; // only for Profiler.php mode; avoids OOM errors |
709 | 724 | } |
Index: branches/querypage-work2/phase3/maintenance/purgeOldText.inc |
— | — | @@ -21,7 +21,7 @@ |
22 | 22 | # Get "active" text records from the revisions table |
23 | 23 | echo( "Searching for active text records in revisions table..." ); |
24 | 24 | $res = $dbw->query( "SELECT DISTINCT rev_text_id FROM $tbl_rev" ); |
25 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
| 25 | + foreach ( $res as $row ) { |
26 | 26 | $cur[] = $row->rev_text_id; |
27 | 27 | } |
28 | 28 | echo( "done.\n" ); |
— | — | @@ -29,7 +29,7 @@ |
30 | 30 | # Get "active" text records from the archive table |
31 | 31 | echo( "Searching for active text records in archive table..." ); |
32 | 32 | $res = $dbw->query( "SELECT DISTINCT ar_text_id FROM $tbl_arc" ); |
33 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
| 33 | + foreach ( $res as $row ) { |
34 | 34 | $cur[] = $row->ar_text_id; |
35 | 35 | } |
36 | 36 | echo( "done.\n" ); |
— | — | @@ -39,7 +39,7 @@ |
40 | 40 | $set = implode( ', ', $cur ); |
41 | 41 | $res = $dbw->query( "SELECT old_id FROM $tbl_txt WHERE old_id NOT IN ( $set )" ); |
42 | 42 | $old = array(); |
43 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
| 43 | + foreach ( $res as $row ) { |
44 | 44 | $old[] = $row->old_id; |
45 | 45 | } |
46 | 46 | echo( "done.\n" ); |
Index: branches/querypage-work2/phase3/maintenance/tables.sql |
— | — | @@ -492,7 +492,7 @@ |
493 | 493 | -- A binary string obtained by applying a sortkey generation algorithm |
494 | 494 | -- (Language::convertToSortkey()) to page_title, or cl_sortkey_prefix . "\0" |
495 | 495 | -- . page_title if cl_sortkey_prefix is nonempty. |
496 | | - cl_sortkey varbinary(255) NOT NULL default '', |
| 496 | + cl_sortkey varbinary(230) NOT NULL default '', |
497 | 497 | |
498 | 498 | -- A prefix for the raw sortkey manually specified by the user, either via |
499 | 499 | -- [[Category:Foo|prefix]] or {{defaultsort:prefix}}. If nonempty, it's |
Property changes on: branches/querypage-work2/phase3/maintenance/tables.sql |
___________________________________________________________________ |
Modified: svn:mergeinfo |
500 | 500 | Merged /trunk/phase3/maintenance/tables.sql:r74568,74575,74577-74581,74584-74585,74587,74589,74591,74595-74596,74606-74607,74614,74625,74627-74628,74643,74646,74677,74679,74681-74684,74686,74688,74691-74692,74695,74697,74703-74704,74725,74727,74731,74740,74742-74750,74752-74753,74755,74771,74778,74780,74784,74786-74787,74789-74790,74792,74795-74798,74800,74804,74806,74810,74820-74822,74824-74825,74827,74831-74832,74836-74837,74841,74843,74847,74849-74851,74855,74859,74884,74891,74896,74898-74899,74901-74902,74904,74910-74914,74918-74920,74922,74932,74934,74943-74957,74959,74962,74964,74966,74969,74975,74978,74981,74988,75002-75003,75006,75018-75019,75021-75022,75024-75025,75029-75031,75035-75037,75040,75054-75057,75059-75061,75064,75066,75068,75083-75084,75087-75088,75096,75098,75100,75102 |
Index: branches/querypage-work2/phase3/maintenance/fixSlaveDesync.php |
— | — | @@ -28,9 +28,8 @@ |
29 | 29 | } |
30 | 30 | |
31 | 31 | public function execute() { |
32 | | - global $wgDBservers; |
33 | 32 | $this->slaveIndexes = array(); |
34 | | - for ( $i = 1; $i < count( $wgDBservers ); $i++ ) { |
| 33 | + for ( $i = 1; $i < wfGetLB()->getServerCount(); $i++ ) { |
35 | 34 | if ( wfGetLB()->isNonZeroLoad( $i ) ) { |
36 | 35 | $this->slaveIndexes[] = $i; |
37 | 36 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/SimpleSeleniumTestSuite.php |
— | — | @@ -1,7 +1,20 @@ |
2 | 2 | <?php |
3 | | - |
| 3 | +/* |
| 4 | + * Sample test suite. |
| 5 | + * Two ways to configure MW for these tests |
| 6 | + * 1) If you are running multiple test suites, add the following in LocalSettings.php |
| 7 | + * require_once("maintenance/tests/selenium/SimpleSeleniumConfig.php"); |
| 8 | + * $wgSeleniumTestConfigs['SimpleSeleniumTestSuite'] = 'SimpleSeleniumConfig::getSettings'; |
| 9 | + * OR |
| 10 | + * 2) Add the following to your Localsettings.php |
| 11 | + * $wgDefaultSkin = 'chick'; |
| 12 | + */ |
4 | 13 | class SimpleSeleniumTestSuite extends SeleniumTestSuite |
5 | 14 | { |
| 15 | + public function setUp() { |
| 16 | + $this->setLoginBeforeTests( false ); |
| 17 | + parent::setUp(); |
| 18 | + } |
6 | 19 | public function addTests() { |
7 | 20 | $testFiles = array( |
8 | 21 | 'maintenance/tests/selenium/SimpleSeleniumTestCase.php' |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/selenium_settings.ini.php52.sample |
— | — | @@ -0,0 +1,22 @@ |
| 2 | +[browsers] |
| 3 | + |
| 4 | +firefox = "*firefox" |
| 5 | +iexploreproxy = "*iexploreproxy" |
| 6 | +chrome = "*chrome" |
| 7 | + |
| 8 | +[SeleniumSettings] |
| 9 | + |
| 10 | +host = "localhost" |
| 11 | +port = "4444" |
| 12 | +wikiUrl = "http://localhost/mediawiki/latest_trunk/trunk/phase3" |
| 13 | +username = "Wikiadmin" |
| 14 | +userPassword = "Wikiadminpw" |
| 15 | +testBrowser = "firefox" |
| 16 | +startserver = |
| 17 | +stopserver = |
| 18 | +jUnitLogFile = |
| 19 | + |
| 20 | +[testSuite] |
| 21 | + |
| 22 | +SimpleSeleniumTestSuite = "maintenance/tests/selenium/SimpleSeleniumTestSuite.php" |
| 23 | +PagedTiffHandlerSeleniumTestSuite = "extensions/PagedTiffHandler/selenium/PagedTiffHandlerTestSuite.php" |
Property changes on: branches/querypage-work2/phase3/maintenance/tests/selenium/selenium_settings.ini.php52.sample |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 24 | + native |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/SeleniumConfig.php |
— | — | @@ -10,6 +10,7 @@ |
11 | 11 | * See sample config file in selenium_settings.ini.sample |
12 | 12 | * |
13 | 13 | */ |
| 14 | + |
14 | 15 | public static function getSeleniumSettings ( &$seleniumSettings, |
15 | 16 | &$seleniumBrowsers, |
16 | 17 | &$seleniumTestSuites, |
— | — | @@ -23,7 +24,16 @@ |
24 | 25 | throw new MWException( "Unable to read local Selenium Settings from " . $seleniumConfigFile . "\n" ); |
25 | 26 | } |
26 | 27 | |
27 | | - $configArray = parse_ini_file($seleniumConfigFile, true); |
| 28 | + if ( !defined( 'PHP_VERSION_ID' ) || |
| 29 | + ( PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 3 ) ) { |
| 30 | + $configArray = self::parse_5_2_ini_file( $seleniumConfigFile ); |
| 31 | + } else { |
| 32 | + $configArray = parse_ini_file( $seleniumConfigFile, true ); |
| 33 | + } |
| 34 | + if ( $configArray === false ) { |
| 35 | + throw new MWException( "Error parsing " . $seleniumConfigFile . "\n" ); |
| 36 | + } |
| 37 | + |
28 | 38 | if ( array_key_exists( 'SeleniumSettings', $configArray) ) { |
29 | 39 | wfSuppressWarnings(); |
30 | 40 | //we may need to change how this is set. But for now leave it in the ini file |
— | — | @@ -34,7 +44,12 @@ |
35 | 45 | $seleniumSettings['wikiUrl'] = $configArray['SeleniumSettings']['wikiUrl']; |
36 | 46 | $seleniumSettings['username'] = $configArray['SeleniumSettings']['username']; |
37 | 47 | $seleniumSettings['userPassword'] = $configArray['SeleniumSettings']['userPassword']; |
38 | | - $seleniumSettings['testBrowser'] = $configArray['SeleniumSettings']['testBrowser']; |
| 48 | + $seleniumSettings['testBrowser'] = $configArray['SeleniumSettings']['testBrowser']; |
| 49 | + $seleniumSettings['startserver'] = $configArray['SeleniumSettings']['startserver']; |
| 50 | + $seleniumSettings['stopserver'] = $configArray['SeleniumSettings']['stopserver']; |
| 51 | + $seleniumSettings['seleniumserverexecpath'] = $configArray['SeleniumSettings']['seleniumserverexecpath']; |
| 52 | + $seleniumSettings['jUnitLogFile'] = $configArray['SeleniumSettings']['jUnitLogFile']; |
| 53 | + |
39 | 54 | wfRestoreWarnings(); |
40 | 55 | } |
41 | 56 | if ( array_key_exists( 'SeleniumTests', $configArray) ) { |
— | — | @@ -45,4 +60,28 @@ |
46 | 61 | return true; |
47 | 62 | } |
48 | 63 | |
| 64 | + private static function parse_5_2_ini_file ( $ConfigFile ) { |
| 65 | + |
| 66 | + $configArray = parse_ini_file( $ConfigFile, true ); |
| 67 | + if ( $configArray === false ) return false; |
| 68 | + |
| 69 | + // PHP 5.2 ini files have [browsers] and [testSuite] sections |
| 70 | + // to get around lack of support for array keys. It then |
| 71 | + // inserts the section arrays into the appropriate places in |
| 72 | + // the SeleniumSettings and SeleniumTests arrays. |
| 73 | + |
| 74 | + if ( isset( $configArray['browsers'] ) ) { |
| 75 | + $configArray['SeleniumSettings']['browsers'] = $configArray['browsers']; |
| 76 | + unset ( $configArray['browsers'] ); |
| 77 | + } |
| 78 | + |
| 79 | + if ( isset( $configArray['testSuite'] ) ) { |
| 80 | + $configArray['SeleniumTests']['testSuite'] = $configArray['testSuite']; |
| 81 | + unset ( $configArray['testSuite'] ); |
| 82 | + } |
| 83 | + |
| 84 | + return $configArray; |
| 85 | + |
| 86 | + } |
| 87 | + |
49 | 88 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/SimpleSeleniumTestCase.php |
— | — | @@ -1,9 +1,10 @@ |
2 | 2 | <?php |
3 | | - |
4 | | -class SimpleSeleniumTestCase extends SeleniumTestCase |
5 | | -{ |
6 | | - public function testBasic() |
7 | | - { |
| 3 | +/* |
| 4 | + * This test case is part of the SimpleSeleniumTestSuite. |
| 5 | + * Configuration for these tests are dosumented as part of SimpleSeleniumTestSuite.php |
| 6 | + */ |
| 7 | +class SimpleSeleniumTestCase extends SeleniumTestCase { |
| 8 | + public function testBasic() { |
8 | 9 | $this->open( $this->getUrl() . |
9 | 10 | '/index.php?title=Selenium&action=edit' ); |
10 | 11 | $this->type( "wpTextbox1", "This is a basic test" ); |
— | — | @@ -14,19 +15,16 @@ |
15 | 16 | $source = $this->getText( "//div[@id='wikiPreview']/p" ); |
16 | 17 | $correct = strstr( $source, "This is a basic test" ); |
17 | 18 | $this->assertEquals( $correct, true ); |
18 | | - |
19 | 19 | } |
20 | 20 | |
21 | 21 | /* |
22 | | - * Needs the following in your LocalConfig or an alternative method of configuration (coming soon) |
23 | | - * require_once( "$IP/extensions/UsabilityInitiative/Vector/Vector.php" ); |
24 | | - * $wgDefaultSkin='vector'; |
| 22 | + * All this test really does is verify that a global var was set. |
| 23 | + * It depends on $wgDefaultSkin = 'chick'; being set |
25 | 24 | */ |
26 | | - public function testGlobalVariable1() |
27 | | - { |
| 25 | + public function testGlobalVariableForDefaultSkin() { |
28 | 26 | $this->open( $this->getUrl() . '/index.php?&action=purge' ); |
29 | 27 | $bodyClass = $this->getAttribute( "//body/@class" ); |
30 | | - $this-> assertContains('skin-vector', $bodyClass, 'Vector skin not set'); |
| 28 | + $this-> assertContains('skin-chick', $bodyClass, 'Chick skin not set'); |
31 | 29 | } |
32 | 30 | |
33 | 31 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/selenium_settings.ini.sample |
— | — | @@ -1,15 +1,29 @@ |
2 | 2 | [SeleniumSettings] |
3 | 3 | |
| 4 | +; Set up the available browsers that Selenium can control. |
4 | 5 | browsers[firefox] = "*firefox" |
5 | 6 | browsers[iexplorer] = "*iexploreproxy" |
6 | 7 | browsers[chrome] = "*chrome" |
| 8 | + |
| 9 | +; The simple configurations above usually work on Linux, but Windows and |
| 10 | +; Mac OS X hosts may need to specify a full path: |
| 11 | +;browsers[firefox] = "*firefox /Applications/Firefox.app/Contents/MacOS/firefox-bin" |
| 12 | +;browsers[firefox] = "*firefox C:\Program Files\Mozilla Firefox\firefox.exe" |
| 13 | + |
7 | 14 | host = "localhost" |
8 | 15 | port = "4444" |
9 | 16 | wikiUrl = "http://localhost/deployment" |
10 | 17 | username = "wikiuser" |
11 | 18 | userPassword = "wikipass" |
12 | 19 | testBrowser = "firefox" |
| 20 | +startserver = |
| 21 | +stopserver = |
| 22 | +jUnitLogFile = |
13 | 23 | |
| 24 | +; To let the test runner start and stop the selenium server, it needs the full |
| 25 | +; path to selenium-server.jar from the selenium-remote-control package. |
| 26 | +seleniumserverexecpath = "/opt/local/selenium-remote-control-1.0.3/selenium-server-1.0.3/selenium-server.jar" |
| 27 | + |
14 | 28 | [SeleniumTests] |
15 | 29 | |
16 | 30 | testSuite[SimpleSeleniumTestSuite] = "maintenance/tests/selenium/SimpleSeleniumTestSuite.php" |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/SeleniumTestSuite.php |
— | — | @@ -3,6 +3,7 @@ |
4 | 4 | abstract class SeleniumTestSuite extends PHPUnit_Framework_TestSuite { |
5 | 5 | private $selenium; |
6 | 6 | private $isSetUp = false; |
| 7 | + private $loginBeforeTests = true; |
7 | 8 | |
8 | 9 | // Do not add line break after test output |
9 | 10 | const CONTINUE_LINE = 1; |
— | — | @@ -20,12 +21,14 @@ |
21 | 22 | $this->isSetUp = true; |
22 | 23 | $this->selenium = Selenium::getInstance(); |
23 | 24 | $this->selenium->start(); |
24 | | - //$this->selenium->open( $this->selenium->getUrl() . '/index.php?setupTestSuite=' . $this->getName() ); |
25 | | - $this->login(); |
| 25 | + $this->selenium->open( $this->selenium->getUrl() . '/index.php?setupTestSuite=' . $this->getName() ); |
| 26 | + if ( $this->loginBeforeTests ) { |
| 27 | + $this->login(); |
| 28 | + } |
26 | 29 | } |
27 | 30 | |
28 | 31 | public function tearDown() { |
29 | | - //$this->selenium->open( $this->selenium->getUrl() . '/index.php?clearTestSuite=' . $this->getName() ); |
| 32 | + $this->selenium->open( $this->selenium->getUrl() . '/index.php?clearTestSuite=' . $this->getName() ); |
30 | 33 | $this->selenium->stop(); |
31 | 34 | } |
32 | 35 | |
— | — | @@ -36,4 +39,8 @@ |
37 | 40 | public function loadPage( $title, $action ) { |
38 | 41 | $this->selenium->loadPage( $title, $action ); |
39 | 42 | } |
| 43 | + |
| 44 | + protected function setLoginBeforeTests( $loginBeforeTests = true ) { |
| 45 | + $this->loginBeforeTests = $loginBeforeTests; |
| 46 | + } |
40 | 47 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/Selenium.php |
— | — | @@ -21,6 +21,7 @@ |
22 | 22 | protected $pass; |
23 | 23 | protected $timeout = 30000; |
24 | 24 | protected $verbose; |
| 25 | + protected $junitlogfile; //processed by phpUnderControl |
25 | 26 | |
26 | 27 | /** |
27 | 28 | * @todo this shouldn't have to be static |
— | — | @@ -112,6 +113,10 @@ |
113 | 114 | $this->port = $port; |
114 | 115 | } |
115 | 116 | |
| 117 | + public function getPort() { |
| 118 | + return $this->port; |
| 119 | + } |
| 120 | + |
116 | 121 | public function setUser( $user ) { |
117 | 122 | $this->user = $user; |
118 | 123 | } |
— | — | @@ -132,6 +137,14 @@ |
133 | 138 | $this->browsers = $availableBrowsers; |
134 | 139 | } |
135 | 140 | |
| 141 | + public function setJUnitLogfile( $junitlogfile ) { |
| 142 | + $this->junitlogfile = $junitlogfile; |
| 143 | + } |
| 144 | + |
| 145 | + public function getJUnitLogfile( ) { |
| 146 | + return $this->junitlogfile; |
| 147 | + } |
| 148 | + |
136 | 149 | public function setBrowser( $b ) { |
137 | 150 | if ( !isset( $this->browsers[$b] ) ) { |
138 | 151 | throw new MWException( "Invalid Browser: $b.\n" ); |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/SimpleSeleniumConfig.php |
— | — | @@ -0,0 +1,15 @@ |
| 2 | +<?php |
| 3 | +class SimpleSeleniumConfig { |
| 4 | + |
| 5 | + public static function getSettings(&$includeFiles, &$globalConfigs) { |
| 6 | + $includes = array( |
| 7 | + //files that needed to be included would go here |
| 8 | + ); |
| 9 | + $configs = array( |
| 10 | + 'wgDefaultSkin' => 'chick' |
| 11 | + ); |
| 12 | + $includeFiles = array_merge( $includeFiles, $includes ); |
| 13 | + $globalConfigs = array_merge( $globalConfigs, $configs); |
| 14 | + return true; |
| 15 | + } |
| 16 | +} |
\ No newline at end of file |
Property changes on: branches/querypage-work2/phase3/maintenance/tests/selenium/SimpleSeleniumConfig.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 17 | + native |
Index: branches/querypage-work2/phase3/maintenance/tests/selenium/SeleniumServerManager.php |
— | — | @@ -0,0 +1,239 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Selenium server manager |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Maintenance |
| 8 | + * Copyright (C) 2010 Dan Nessett <dnessett@yahoo.com> |
| 9 | + * http://citizendium.org/ |
| 10 | + * |
| 11 | + * This program is free software; you can redistribute it and/or modify |
| 12 | + * it under the terms of the GNU General Public License as published by |
| 13 | + * the Free Software Foundation; either version 2 of the License, or |
| 14 | + * (at your option) any later version. |
| 15 | + * |
| 16 | + * This program is distributed in the hope that it will be useful, |
| 17 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 19 | + * GNU General Public License for more details. |
| 20 | + * |
| 21 | + * You should have received a copy of the GNU General Public License along |
| 22 | + * with this program; if not, write to the Free Software Foundation, Inc., |
| 23 | + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 24 | + * http://www.gnu.org/copyleft/gpl.html |
| 25 | + * |
| 26 | + * @addtogroup Maintenance |
| 27 | + */ |
| 28 | + |
| 29 | +class SeleniumServerManager { |
| 30 | + private $SeleniumStartServer = false; |
| 31 | + private $OS = ''; |
| 32 | + private $SeleniumServerPid = 'NaN'; |
| 33 | + private $SeleniumServerPort = 4444; |
| 34 | + private $SeleniumServerStartTimeout = 10; // 10 secs. |
| 35 | + private $SeleniumServerExecPath; |
| 36 | + |
| 37 | + public function __construct( $startServer, |
| 38 | + $serverPort, |
| 39 | + $serverExecPath ) { |
| 40 | + $this->OS = (string) PHP_OS; |
| 41 | + if ( isset( $startServer ) ) |
| 42 | + $this->SeleniumStartServer = $startServer; |
| 43 | + if ( isset( $serverPort ) ) |
| 44 | + $this->SeleniumServerPort = $serverPort; |
| 45 | + if ( isset( $serverExecPath ) ) |
| 46 | + $this->SeleniumServerExecPath = $serverExecPath; |
| 47 | + return; |
| 48 | + } |
| 49 | + |
| 50 | + // Getters for certain private attributes. No setters, since they |
| 51 | + // should not change after the manager object is created. |
| 52 | + |
| 53 | + public function getSeleniumStartServer() { |
| 54 | + return $this->SeleniumStartServer; |
| 55 | + } |
| 56 | + |
| 57 | + public function getSeleniumServerPort() { |
| 58 | + return $this->SeleniumServerPort; |
| 59 | + } |
| 60 | + |
| 61 | + public function getSeleniumServerPid() { |
| 62 | + return $this->SeleniumServerPid; |
| 63 | + } |
| 64 | + |
| 65 | + // Changing value of SeleniumStartServer allows starting server after |
| 66 | + // creation of the class instance. Only allow setting SeleniumStartServer |
| 67 | + // to true, since after server is started, it is shut down by stop(). |
| 68 | + |
| 69 | + public function setSeleniumStartServer( $startServer ) { |
| 70 | + if ( $startServer == true ) $this->SeleniumStartServer = true; |
| 71 | + } |
| 72 | + |
| 73 | + // return values are: 1) started - server started, 2) failed - |
| 74 | + // server not started, 3) running - instructed to start server, but |
| 75 | + // server already running |
| 76 | + |
| 77 | + public function start() { |
| 78 | + |
| 79 | + if ( !$this->SeleniumStartServer ) return 'failed'; |
| 80 | + |
| 81 | + // commented out cases are untested |
| 82 | + |
| 83 | + switch ( $this->OS ) { |
| 84 | + case "Linux": |
| 85 | +# case' CYGWIN_NT-5.1': |
| 86 | + case 'Darwin': |
| 87 | +# case 'FreeBSD': |
| 88 | +# case 'HP-UX': |
| 89 | +# case 'IRIX64': |
| 90 | +# case 'NetBSD': |
| 91 | +# case 'OpenBSD': |
| 92 | +# case 'SunOS': |
| 93 | +# case 'Unix': |
| 94 | + // *nix based OS |
| 95 | + return $this->startServerOnUnix(); |
| 96 | + break; |
| 97 | + case "Windows": |
| 98 | + case "WIN32": |
| 99 | + case "WINNT": |
| 100 | + // Windows |
| 101 | + return $this->startServerOnWindows(); |
| 102 | + break; |
| 103 | + default: |
| 104 | + // An untested OS |
| 105 | + return 'failed'; |
| 106 | + break; |
| 107 | + } |
| 108 | + } |
| 109 | + |
| 110 | + public function stop() { |
| 111 | + |
| 112 | + // commented out cases are untested |
| 113 | + |
| 114 | + switch ( $this->OS ) { |
| 115 | + case "Linux": |
| 116 | +# case' CYGWIN_NT-5.1': |
| 117 | + case 'Darwin': |
| 118 | +# case 'FreeBSD': |
| 119 | +# case 'HP-UX': |
| 120 | +# case 'IRIX64': |
| 121 | +# case 'NetBSD': |
| 122 | +# case 'OpenBSD': |
| 123 | +# case 'SunOS': |
| 124 | +# case 'Unix': |
| 125 | + // *nix based OS |
| 126 | + return $this->stopServerOnUnix(); |
| 127 | + break; |
| 128 | + case "Windows": |
| 129 | + case "WIN32": |
| 130 | + case "WINNT": |
| 131 | + // Windows |
| 132 | + return $this->stopServerOnWindows(); |
| 133 | + break; |
| 134 | + default: |
| 135 | + // An untested OS |
| 136 | + return 'failed'; |
| 137 | + break; |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + private function startServerOnUnix() { |
| 142 | + |
| 143 | + $output = array(); |
| 144 | + $user = $_ENV['USER']; |
| 145 | + // @fixme this should be a little more generalized :) |
| 146 | + if (PHP_OS == 'Darwin') { |
| 147 | + // Mac OS X's ps barfs on the 'w' param, but doesn't need it. |
| 148 | + $ps = "ps -U %s"; |
| 149 | + } else { |
| 150 | + // Good on Linux |
| 151 | + $ps = "ps -U %s w"; |
| 152 | + } |
| 153 | + $psCommand = sprintf($ps, escapeshellarg($user)); |
| 154 | + exec($psCommand . " | grep -i selenium-server", $output); |
| 155 | + |
| 156 | + // Start server. If there is already a server running, |
| 157 | + // return running. |
| 158 | + |
| 159 | + if ( isset( $this->SeleniumServerExecPath ) ) { |
| 160 | + $found = 0; |
| 161 | + foreach ( $output as $string ) { |
| 162 | + $found += preg_match( |
| 163 | + '~^(.*)java(.+)-jar(.+)selenium-server~', |
| 164 | + $string ); |
| 165 | + } |
| 166 | + if ( $found == 0 ) { |
| 167 | + |
| 168 | + // Didn't find the selenium server. Start it up. |
| 169 | + // First set up comamand line suffix. |
| 170 | + // NB: $! is pid of last job run in background |
| 171 | + // The echo guarentees it is put into $op when |
| 172 | + // the exec command is run. |
| 173 | + |
| 174 | + $commandSuffix = ' > /dev/null 2>&1'. ' & echo $!'; |
| 175 | + $portText = ' -port ' . $this->SeleniumServerPort; |
| 176 | + $command = "java -jar " . |
| 177 | + escapeshellarg($this->SeleniumServerExecPath) . |
| 178 | + $portText . $commandSuffix; |
| 179 | + exec($command ,$op); |
| 180 | + $pid = (int)$op[0]; |
| 181 | + if ( $pid != "" ) |
| 182 | + $this->SeleniumServerPid = $pid; |
| 183 | + else { |
| 184 | + $this->SeleniumServerPid = 'NaN'; |
| 185 | + // Server start failed. |
| 186 | + return 'failed'; |
| 187 | + } |
| 188 | + // Wait for the server to startup and listen |
| 189 | + // on its port. Note: this solution kinda |
| 190 | + // stinks, since it uses a wait loop - dnessett |
| 191 | + |
| 192 | + wfSuppressWarnings(); |
| 193 | + for ( $cnt = 1; |
| 194 | + $cnt <= $this->SeleniumServerStartTimeout; |
| 195 | + $cnt++ ) { |
| 196 | + $fp = fsockopen ( 'localhost', |
| 197 | + $this->SeleniumServerPort, |
| 198 | + $errno, $errstr, 0 ); |
| 199 | + if ( !$fp ) { |
| 200 | + sleep( 1 ); |
| 201 | + continue; |
| 202 | + // Server start succeeded. |
| 203 | + } else { |
| 204 | + fclose ( $fp ); |
| 205 | + return 'started'; |
| 206 | + } |
| 207 | + } |
| 208 | + wfRestoreWarnings(); |
| 209 | + echo ( "Starting Selenium server timed out.\n" ); |
| 210 | + return 'failed'; |
| 211 | + } |
| 212 | + // server already running. |
| 213 | + else return 'running'; |
| 214 | + |
| 215 | + } |
| 216 | + // No Server execution path defined. |
| 217 | + return 'failed'; |
| 218 | + } |
| 219 | + |
| 220 | + private function startServerOnWindows() { |
| 221 | + // Unimplemented. |
| 222 | + return 'failed'; |
| 223 | + } |
| 224 | + |
| 225 | + private function stopServerOnUnix() { |
| 226 | + |
| 227 | + if ( !empty( $this->SeleniumServerPid ) && |
| 228 | + $this->SeleniumServerPid != 'NaN' ) { |
| 229 | + exec( "kill -9 " . $this->SeleniumServerPid ); |
| 230 | + return 'stopped'; |
| 231 | + } |
| 232 | + else return 'failed'; |
| 233 | + } |
| 234 | + |
| 235 | + private function stopServerOnWindows() { |
| 236 | + // Unimplemented. |
| 237 | + return 'failed'; |
| 238 | + |
| 239 | + } |
| 240 | +} |
Property changes on: branches/querypage-work2/phase3/maintenance/tests/selenium/SeleniumServerManager.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 241 | + native |
Added: svn:keywords |
2 | 242 | + LastChangedDate LastChangedBy Revision Id |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/bootstrap.php |
— | — | @@ -31,33 +31,22 @@ |
32 | 32 | /* Classes */ |
33 | 33 | |
34 | 34 | abstract class MediaWikiTestSetup extends PHPUnit_Framework_TestCase { |
| 35 | + protected $suite; |
| 36 | + public $regex = ''; |
| 37 | + public $runDisabled = false; |
35 | 38 | |
36 | | - protected function buildTestDatabase( $tables ) { |
37 | | - global $wgDBprefix; |
38 | | - |
39 | | - $db = wfGetDB( DB_MASTER ); |
40 | | - $oldTableNames = array(); |
41 | | - foreach ( $tables as $table ) |
42 | | - $oldTableNames[$table] = $db->tableName( $table ); |
43 | | - if ( $db->getType() == 'oracle' ) { |
44 | | - $wgDBprefix = 'pt_'; |
45 | | - } else { |
46 | | - $wgDBprefix = 'parsertest_'; |
| 39 | + function __construct( PHPUnit_Framework_TestSuite $suite = null ) { |
| 40 | + if ( null !== $suite ) { |
| 41 | + $this->suite = $suite; |
47 | 42 | } |
| 43 | + } |
48 | 44 | |
49 | | - $db->tablePrefix( $wgDBprefix ); |
50 | | - |
51 | | - if ( $db->isOpen() ) { |
52 | | - foreach ( $tables as $tbl ) { |
53 | | - $newTableName = $db->tableName( $tbl ); |
54 | | - $tableName = $oldTableNames[$tbl]; |
55 | | - $db->query( "DROP TABLE IF EXISTS $newTableName", __METHOD__ ); |
56 | | - $db->duplicateTableStructure( $tableName, $newTableName, __METHOD__ ); |
57 | | - } |
58 | | - return $db; |
| 45 | + function __call( $func, $args ) { |
| 46 | + if ( method_exists( $this->suite, $func ) ) { |
| 47 | + return call_user_func_array( array( $this->suite, $func ), $args); |
59 | 48 | } else { |
60 | | - // Something amiss |
61 | | - return null; |
| 49 | + throw new MWException( "Called non-existant $func method on " |
| 50 | + . get_class( $this ) ); |
62 | 51 | } |
63 | 52 | } |
64 | 53 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/db/DatabaseSqliteTest.php |
— | — | @@ -23,7 +23,7 @@ |
24 | 24 | class DatabaseSqliteTest extends PHPUnit_Framework_TestCase { |
25 | 25 | var $db; |
26 | 26 | |
27 | | - public function setup() { |
| 27 | + public function setUp() { |
28 | 28 | if ( !Sqlite::isPresent() ) { |
29 | 29 | $this->markTestSkipped( 'No SQLite support detected' ); |
30 | 30 | } |
— | — | @@ -84,4 +84,4 @@ |
85 | 85 | $this->fail( $result ); |
86 | 86 | } |
87 | 87 | } |
88 | | -} |
| 88 | +} |
\ No newline at end of file |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/ExtraParserTest.php |
— | — | @@ -23,11 +23,14 @@ |
24 | 24 | |
25 | 25 | // Bug 8689 - Long numeric lines kill the parser |
26 | 26 | function testBug8689() { |
| 27 | + global $wgLang; |
| 28 | + global $wgUser; |
27 | 29 | $longLine = '1.' . str_repeat( '1234567890', 100000 ) . "\n"; |
28 | 30 | |
| 31 | + if ( $wgLang === null ) $wgLang = new Language; |
29 | 32 | $parser = new Parser(); |
30 | 33 | $t = Title::newFromText( 'Unit test' ); |
31 | | - $options = new ParserOptions(); |
| 34 | + $options = ParserOptions::newFromUser( $wgUser ); |
32 | 35 | $this->assertEquals( "<p>$longLine</p>", |
33 | 36 | $parser->parse( $longLine, $t, $options )->getText() ); |
34 | 37 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/parser/ParserHelpers.php |
— | — | @@ -1,5 +1,21 @@ |
2 | 2 | <?php |
3 | 3 | |
| 4 | +class PHPUnitParserTest extends ParserTest { |
| 5 | + function showTesting( $desc ) { |
| 6 | + /* Do nothing since we don't want to show info during PHPUnit testing. */ |
| 7 | + } |
| 8 | + |
| 9 | + public function showSuccess( $desc ) { |
| 10 | + PHPUnit_Framework_Assert::assertTrue( true, $desc ); |
| 11 | + return true; |
| 12 | + } |
| 13 | + |
| 14 | + public function showFailure( $desc, $expected, $got ) { |
| 15 | + PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc ); |
| 16 | + return false; |
| 17 | + } |
| 18 | +} |
| 19 | + |
4 | 20 | class ParserUnitTest extends PHPUnit_Framework_TestCase { |
5 | 21 | private $test = ""; |
6 | 22 | private $suite; |
— | — | @@ -17,9 +33,9 @@ |
18 | 34 | $result = new PHPUnit_Framework_TestResult; |
19 | 35 | } |
20 | 36 | |
21 | | - $backend = $this->suite->getBackend(); |
| 37 | + $backend = new ParserTestSuiteBackend; |
22 | 38 | $result->startTest( $this ); |
23 | | - |
| 39 | + |
24 | 40 | // Support the transition to PHPUnit 3.5 where PHPUnit_Util_Timer is replaced with PHP_Timer |
25 | 41 | if ( class_exists( 'PHP_Timer' ) ) { |
26 | 42 | PHP_Timer::start(); |
— | — | @@ -32,16 +48,13 @@ |
33 | 49 | # Run the test. |
34 | 50 | # On failure, the subclassed backend will throw an exception with |
35 | 51 | # the details. |
36 | | - $r = $backend->runTest( |
37 | | - $this->test['test'], |
38 | | - $this->test['input'], |
39 | | - $this->test['result'], |
40 | | - $this->test['options'], |
41 | | - $this->test['config'] |
| 52 | + $pt = new PHPUnitParserTest; |
| 53 | + $r = $pt->runTest( $this->test['test'], $this->test['input'], |
| 54 | + $this->test['result'], $this->test['options'], $this->test['config'] |
42 | 55 | ); |
43 | 56 | } |
44 | 57 | catch ( PHPUnit_Framework_AssertionFailedError $e ) { |
45 | | - |
| 58 | + |
46 | 59 | // PHPUnit_Util_Timer -> PHP_Timer support (see above) |
47 | 60 | if ( class_exists( 'PHP_Timer' ) ) { |
48 | 61 | $result->addFailure( $this, $e, PHP_Timer::stop() ); |
— | — | @@ -77,20 +90,29 @@ |
78 | 91 | |
79 | 92 | } |
80 | 93 | |
81 | | -class ParserTestSuiteBackend extends ParserTest { |
| 94 | +class ParserTestSuiteBackend extends PHPUnit_FrameWork_TestSuite { |
| 95 | + public $recorder; |
| 96 | + public $term; |
| 97 | + static $usePHPUnit = false; |
| 98 | + |
| 99 | + function __construct() { |
| 100 | + parent::__construct(); |
| 101 | + $this->setupRecorder(null); |
| 102 | + self::$usePHPUnit = method_exists('PHPUnit_Framework_Assert', 'assertEquals'); |
| 103 | + } |
| 104 | + |
82 | 105 | function showTesting( $desc ) { |
83 | 106 | } |
84 | 107 | |
85 | 108 | function showRunFile( $path ) { |
86 | 109 | } |
87 | 110 | |
88 | | - function showSuccess( $desc ) { |
89 | | - PHPUnit_Framework_Assert::assertTrue( true, $desc ); |
90 | | - return true; |
| 111 | + function showTestResult( $desc, $result, $out ) { |
| 112 | + if ( $result === $out ) { |
| 113 | + return self::showSuccess( $desc, $result, $out ); |
| 114 | + } else { |
| 115 | + return self::showFailure( $desc, $result, $out ); |
91 | 116 | } |
92 | | - |
93 | | - function showFailure( $desc, $expected, $got ) { |
94 | | - PHPUnit_Framework_Assert::assertEquals( $expected, $got, $desc ); |
95 | 117 | } |
96 | 118 | |
97 | 119 | public function setupRecorder( $options ) { |
— | — | @@ -107,4 +129,3 @@ |
108 | 130 | |
109 | 131 | function reportPercentage( $success, $total ) { } |
110 | 132 | } |
111 | | - |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/parser/MediaWikiParserTest.php |
— | — | @@ -1,41 +1,34 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | require_once( dirname( __FILE__ ) . '/ParserHelpers.php' ); |
| 5 | +require_once( dirname(dirname(dirname( __FILE__ ))) . '/bootstrap.php' ); |
5 | 6 | |
6 | | -class MediaWikiParserTest extends PHPUnit_Framework_TestSuite { |
7 | | - private $count; |
| 7 | +class MediaWikiParserTest extends MediaWikiTestSetup { |
| 8 | + public $count; |
8 | 9 | public $backend; |
9 | 10 | |
10 | | - public static function suite() { |
11 | | - return new self; |
12 | | - } |
13 | | - |
14 | 11 | public function __construct() { |
| 12 | + $suite = new PHPUnit_Framework_TestSuite('Parser Tests'); |
| 13 | + parent::__construct($suite); |
15 | 14 | $this->backend = new ParserTestSuiteBackend; |
16 | | - parent::__construct(); |
17 | 15 | $this->setName( 'Parser tests' ); |
18 | 16 | } |
19 | 17 | |
20 | | - public function run( PHPUnit_Framework_TestResult $result = null, $filter = false, |
21 | | - array $groups = array(), array $excludeGroups = array(), $processIsolation = false |
22 | | - ) { |
23 | | - global $IP, $wgContLang, $wgMemc; |
24 | | - $wgContLang = Language::factory( 'en' ); |
25 | | - $wgMemc = new FakeMemCachedClient; |
26 | | - $this->backend->setupDatabase(); |
| 18 | + public static function suite() { |
| 19 | + global $IP; |
27 | 20 | |
| 21 | + $tester = new self; |
| 22 | + |
28 | 23 | $iter = new TestFileIterator( "$IP/maintenance/tests/parser/parserTests.txt" ); |
29 | | - $iter->setParser( $this->backend ); |
30 | | - $this->count = 0; |
| 24 | + $iter->setParser( $tester ); |
| 25 | + $tester->count = 0; |
31 | 26 | |
32 | 27 | foreach ( $iter as $test ) { |
33 | | - $this->addTest( new ParserUnitTest( $this, $test ) ); |
34 | | - $this->count++; |
| 28 | + $tester->suite->addTest( new ParserUnitTest( $tester, $test ), array( 'Parser' ) ); |
| 29 | + $tester->count++; |
35 | 30 | } |
36 | 31 | |
37 | | - parent::run( $result, $filter, $groups, $excludeGroups, $processIsolation ); |
38 | | - |
39 | | - $this->backend->teardownDatabase(); |
| 32 | + return $tester->suite; |
40 | 33 | } |
41 | 34 | |
42 | 35 | public function count() { |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/HttpTest.php |
— | — | @@ -27,7 +27,7 @@ |
28 | 28 | |
29 | 29 | var $test_posturl = array( "http://www.comp.leeds.ac.uk/cgi-bin/Perl/environment-example" => "review=test" ); |
30 | 30 | |
31 | | - function setup() { |
| 31 | + function setUp() { |
32 | 32 | putenv( "http_proxy" ); /* Remove any proxy env var, so curl doesn't get confused */ |
33 | 33 | if ( is_array( self::$content ) ) { |
34 | 34 | return; |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/search/SearchDbTest.php |
— | — | @@ -6,11 +6,15 @@ |
7 | 7 | var $db; |
8 | 8 | |
9 | 9 | function setUp() { |
| 10 | + // Get a database connection or skip test |
10 | 11 | $this->db = wfGetDB( DB_MASTER ); |
11 | 12 | if ( !$this->db ) { |
12 | 13 | $this->markTestIncomplete( "Can't find a database to test with." ); |
13 | 14 | } |
14 | 15 | |
| 16 | + parent::setup(); |
| 17 | + |
| 18 | + // Initialize search database with data |
15 | 19 | $GLOBALS['wgContLang'] = new Language; |
16 | 20 | $this->insertSearchData(); |
17 | 21 | |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/search/SearchEngineTest.php |
— | — | @@ -1,13 +1,31 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | | -require_once dirname(__FILE__) . '/../../bootstrap.php'; |
| 4 | +require_once dirname(dirname(dirname(__FILE__))). '/bootstrap.php'; |
5 | 5 | |
6 | 6 | /** |
| 7 | + * This class is not directly tested. Instead it is extended by SearchDbTest. |
7 | 8 | * @group Stub |
8 | 9 | */ |
9 | 10 | class SearchEngineTest extends MediaWikiTestSetup { |
10 | 11 | var $db, $search, $pageList; |
11 | 12 | |
| 13 | + /* |
| 14 | + * Checks for database type & version. |
| 15 | + * Will skip current test if DB does not support search. |
| 16 | + */ |
| 17 | + function setUp() { |
| 18 | + // Search tests require MySQL or SQLite with FTS |
| 19 | + # Get database type and version |
| 20 | + $dbType = $this->db->getType(); |
| 21 | + $dbSupported = |
| 22 | + ($dbType === 'mysql') |
| 23 | + || ( $dbType === 'sqlite' && $this->db->getFulltextSearchModule() == 'FTS3' ); |
| 24 | + |
| 25 | + if( !$dbSupported ) { |
| 26 | + $this->markTestSkipped( "MySQL or SQLite with FTS3 only" ); |
| 27 | + } |
| 28 | + } |
| 29 | + |
12 | 30 | function pageExists( $title ) { |
13 | 31 | return false; |
14 | 32 | } |
— | — | @@ -47,9 +65,6 @@ |
48 | 66 | function fetchIds( $results ) { |
49 | 67 | $this->assertTrue( is_object( $results ) ); |
50 | 68 | |
51 | | - if ( $this->db->getType() !== 'mysql' && $this->db->getType() !== 'sqlite' ) { |
52 | | - $this->markTestSkipped( "MySQL or SQLite only" ); |
53 | | - } |
54 | 69 | $matches = array(); |
55 | 70 | while ( $row = $results->next() ) { |
56 | 71 | $matches[] = $row->getTitle()->getPrefixedText(); |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/api/ApiTest.php |
— | — | @@ -19,10 +19,6 @@ |
20 | 20 | |
21 | 21 | class ApiTest extends ApiTestSetup { |
22 | 22 | |
23 | | - function setup() { |
24 | | - parent::setup(); |
25 | | - } |
26 | | - |
27 | 23 | function testRequireOnlyOneParameterDefault() { |
28 | 24 | $mock = new MockApi(); |
29 | 25 | |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/UploadTest.php |
— | — | @@ -8,7 +8,7 @@ |
9 | 9 | |
10 | 10 | function setUp() { |
11 | 11 | global $wgContLang; |
12 | | - parent::setup(); |
| 12 | + parent::setUp(); |
13 | 13 | $wgContLang = Language::factory( 'en' ); |
14 | 14 | $this->upload = new UploadTestHandler; |
15 | 15 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/CdbTest.php |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | class CdbTest extends PHPUnit_Framework_TestCase { |
9 | 9 | |
10 | | - public function setup() { |
| 10 | + public function setUp() { |
11 | 11 | if ( !CdbReader::haveExtension() ) { |
12 | 12 | $this->markTestIncomplete( 'This test requires native CDB support to be present.' ); |
13 | 13 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/includes/UploadFromUrlTest.php |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | |
11 | 11 | public function setUp() { |
12 | 12 | global $wgEnableUploads, $wgAllowCopyUploads, $wgAllowAsyncCopyUploads; |
13 | | - parent::setup(); |
| 13 | + parent::setUp(); |
14 | 14 | |
15 | 15 | $wgEnableUploads = true; |
16 | 16 | $wgAllowCopyUploads = true; |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/suite.xml |
— | — | @@ -6,7 +6,8 @@ |
7 | 7 | convertErrorsToExceptions="true" |
8 | 8 | convertNoticesToExceptions="true" |
9 | 9 | convertWarningsToExceptions="true" |
10 | | - stopOnFailure="false"> |
| 10 | + stopOnFailure="false" |
| 11 | + strict="true"> |
11 | 12 | <testsuites> |
12 | 13 | <testsuite name="includes"> |
13 | 14 | <directory>./includes</directory> |
— | — | @@ -26,6 +27,7 @@ |
27 | 28 | </testsuites> |
28 | 29 | <groups> |
29 | 30 | <exclude> |
| 31 | + <group>Utility</group> |
30 | 32 | <group>Broken</group> |
31 | 33 | <group>Stub</group> |
32 | 34 | </exclude> |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/Makefile |
— | — | @@ -1,4 +1,5 @@ |
2 | | -.PHONY: help test phpunit install coverage warning destructive |
| 2 | +.PHONY: help test phpunit install coverage warning destructive parser noparser list-groups |
| 3 | +.DEFAULT: warning |
3 | 4 | |
4 | 5 | SHELL = /bin/sh |
5 | 6 | CONFIG_FILE = $(shell pwd)/suite.xml |
— | — | @@ -8,6 +9,7 @@ |
9 | 10 | all test: warning |
10 | 11 | |
11 | 12 | warning: |
| 13 | + # Use 'make help' to get usage |
12 | 14 | @echo "WARNING -- these tests are DESTRUCTIVE and will alter your wiki." |
13 | 15 | @echo "DO NOT RUN THESE TESTS on a production wiki." |
14 | 16 | @echo "" |
— | — | @@ -32,6 +34,15 @@ |
33 | 35 | coverage: |
34 | 36 | ${PU} --coverage-html ../../../docs/code-coverage |
35 | 37 | |
| 38 | +parser: |
| 39 | + ${PU} --group Parser |
| 40 | + |
| 41 | +noparser: |
| 42 | + ${PU} --exclude-group Parser |
| 43 | + |
| 44 | +list-groups: |
| 45 | + ${PU} --list-groups |
| 46 | + |
36 | 47 | help: |
37 | 48 | # Usage: |
38 | 49 | # make <target> [OPTION=value] |
— | — | @@ -43,6 +54,10 @@ |
44 | 55 | # help You're looking at it! |
45 | 56 | # coverage Run the tests and generates an HTML code coverage report |
46 | 57 | # You will need the Xdebug PHP extension for the later. |
| 58 | + # [no]parser Skip or only run Parser tests |
| 59 | + # |
| 60 | + # list-groups List availabe Tests groups. |
| 61 | + # |
47 | 62 | # Options: |
48 | 63 | # CONFIG_FILE Path to a PHPUnit configuration file (default: suite.xml) |
49 | 64 | # FLAGS Additional flags to pass to PHPUnit |
Index: branches/querypage-work2/phase3/maintenance/tests/phpunit/phpunit.php |
— | — | @@ -23,12 +23,12 @@ |
24 | 24 | // To prevent tests from failing with SQLite, we need to turn database caching off |
25 | 25 | $wgCaches[CACHE_DB] = false; |
26 | 26 | |
27 | | -$targetFile = wfIsWindows() ? 'phpunit.php' : 'phpunit'; |
28 | | -$pathSeparator = wfIsWindows() ? ';' : ':'; |
29 | | - |
30 | | -$folders = explode( $pathSeparator, getenv('PATH') ); |
31 | | - |
32 | | -require 'PHPUnit/TextUI/Command.php'; |
33 | | -define('PHPUnit_MAIN_METHOD', 'PHPUnit_TextUI_Command::main'); |
| 27 | +require_once( 'PHPUnit/Runner/Version.php' ); |
| 28 | +if( version_compare( PHPUnit_Runner_Version::id(), '3.5.0', '>=' ) ) { |
| 29 | + # PHPUnit 3.5.0 introduced a nice autoloader based on class name |
| 30 | + require_once( 'PHPUnit/Autoload.php' ); |
| 31 | +} else { |
| 32 | + # Keep the old pre PHPUnit 3.5.0 behaviour for compatibility |
| 33 | + require_once( 'PHPUnit/TextUI/Command.php' ); |
| 34 | +} |
34 | 35 | PHPUnit_TextUI_Command::main(); |
35 | | - |
Index: branches/querypage-work2/phase3/maintenance/tests/testHelpers.inc |
— | — | @@ -478,7 +478,7 @@ |
479 | 479 | $this->lineNum = $this->index = 0; |
480 | 480 | } |
481 | 481 | |
482 | | - function setParser( ParserTest $parser ) { |
| 482 | + function setParser( MediaWikiParserTest $parser ) { |
483 | 483 | $this->parser = $parser; |
484 | 484 | } |
485 | 485 | |
— | — | @@ -536,11 +536,10 @@ |
537 | 537 | wfDie( "'endarticle' without 'article' at line {$this->lineNum} of $this->file\n" ); |
538 | 538 | } |
539 | 539 | |
540 | | - if ( $this->parser ) { |
541 | | - $this->parser->addArticle( $this->parser->chomp( $data['article'] ), $this->parser->chomp( $data['text'] ), |
542 | | - $this->lineNum ); |
543 | | - } |
544 | | - |
| 540 | + $title = Title::newFromText( ParserTest::chomp( $data['article'] ) ); |
| 541 | + $aid = $title->getArticleID( Title::GAID_FOR_UPDATE ); |
| 542 | + if ( $aid == 0 ) |
| 543 | + ParserTest::addArticle( $data['article'], $data['text'], $this->lineNum ); |
545 | 544 | $data = array(); |
546 | 545 | $section = null; |
547 | 546 | |
— | — | @@ -632,11 +631,11 @@ |
633 | 632 | |
634 | 633 | if ( $this->parser ) { |
635 | 634 | $this->test = array( |
636 | | - 'test' => $this->parser->chomp( $data['test'] ), |
637 | | - 'input' => $this->parser->chomp( $data['input'] ), |
638 | | - 'result' => $this->parser->chomp( $data['result'] ), |
639 | | - 'options' => $this->parser->chomp( $data['options'] ), |
640 | | - 'config' => $this->parser->chomp( $data['config'] ) ); |
| 635 | + 'test' => ParserTest::chomp( $data['test'] ), |
| 636 | + 'input' => ParserTest::chomp( $data['input'] ), |
| 637 | + 'result' => ParserTest::chomp( $data['result'] ), |
| 638 | + 'options' => ParserTest::chomp( $data['options'] ), |
| 639 | + 'config' => ParserTest::chomp( $data['config'] ) ); |
641 | 640 | } else { |
642 | 641 | $this->test['test'] = $data['test']; |
643 | 642 | } |
Index: branches/querypage-work2/phase3/maintenance/tests/parser/parserTest.inc |
— | — | @@ -56,7 +56,10 @@ |
57 | 57 | private $maxFuzzTestLength = 300; |
58 | 58 | private $fuzzSeed = 0; |
59 | 59 | private $memoryLimit = 50; |
| 60 | + private $uploadDir = null; |
60 | 61 | |
| 62 | + public $regex = ""; |
| 63 | + private $savedGlobals = array(); |
61 | 64 | /** |
62 | 65 | * Sets terminal colorization and diff/quick modes depending on OS and |
63 | 66 | * command-line options (--color and --quick). |
— | — | @@ -113,8 +116,59 @@ |
114 | 117 | |
115 | 118 | $this->hooks = array(); |
116 | 119 | $this->functionHooks = array(); |
| 120 | + self::setUp(); |
117 | 121 | } |
118 | 122 | |
| 123 | + static function setUp() { |
| 124 | + global $wgParser, $wgParserConf, $IP, $messageMemc, $wgMemc, $wgDeferredUpdateList, |
| 125 | + $wgUser, $wgLang, $wgOut, $wgRequest, $wgStyleDirectory, $wgEnableParserCache, |
| 126 | + $wgMessageCache, $wgUseDatabaseMessages, $wgMsgCacheExpiry, $parserMemc, |
| 127 | + $wgNamespaceAliases, $wgNamespaceProtection, $wgLocalFileRepo, |
| 128 | + $wgThumbnailScriptPath, $wgScriptPath, |
| 129 | + $wgArticlePath, $wgStyleSheetPath, $wgScript, $wgStylePath; |
| 130 | + |
| 131 | + $wgScript = '/index.php'; |
| 132 | + $wgScriptPath = '/'; |
| 133 | + $wgArticlePath = '/wiki/$1'; |
| 134 | + $wgStyleSheetPath = '/skins'; |
| 135 | + $wgStylePath = '/skins'; |
| 136 | + $wgThumbnailScriptPath = false; |
| 137 | + $wgLocalFileRepo = array( |
| 138 | + 'class' => 'LocalRepo', |
| 139 | + 'name' => 'local', |
| 140 | + 'directory' => wfTempDir() . '/test-repo', |
| 141 | + 'url' => 'http://example.com/images', |
| 142 | + 'deletedDir' => wfTempDir() . '/test-repo/delete', |
| 143 | + 'hashLevels' => 2, |
| 144 | + 'transformVia404' => false, |
| 145 | + ); |
| 146 | + $wgNamespaceProtection[NS_MEDIAWIKI] = 'editinterface'; |
| 147 | + $wgNamespaceAliases['Image'] = NS_FILE; |
| 148 | + $wgNamespaceAliases['Image_talk'] = NS_FILE_TALK; |
| 149 | + |
| 150 | + |
| 151 | + $wgEnableParserCache = false; |
| 152 | + $wgDeferredUpdateList = array(); |
| 153 | + $wgMemc =& wfGetMainCache(); |
| 154 | + $messageMemc =& wfGetMessageCacheStorage(); |
| 155 | + $parserMemc =& wfGetParserCacheStorage(); |
| 156 | + |
| 157 | + // $wgContLang = new StubContLang; |
| 158 | + $wgUser = new User; |
| 159 | + $wgLang = new StubUserLang; |
| 160 | + $wgOut = new StubObject( 'wgOut', 'OutputPage' ); |
| 161 | + $wgParser = new StubObject( 'wgParser', $wgParserConf['class'], array( $wgParserConf ) ); |
| 162 | + $wgRequest = new WebRequest; |
| 163 | + |
| 164 | + $wgMessageCache = new StubObject( 'wgMessageCache', 'MessageCache', |
| 165 | + array( $messageMemc, $wgUseDatabaseMessages, |
| 166 | + $wgMsgCacheExpiry ) ); |
| 167 | + if ( $wgStyleDirectory === false ) { |
| 168 | + $wgStyleDirectory = "$IP/skins"; |
| 169 | + } |
| 170 | + |
| 171 | + } |
| 172 | + |
119 | 173 | public function setupRecorder ( $options ) { |
120 | 174 | if ( isset( $options['record'] ) ) { |
121 | 175 | $this->recorder = new DbTestRecorder( $this ); |
— | — | @@ -131,8 +185,9 @@ |
132 | 186 | |
133 | 187 | /** |
134 | 188 | * Remove last character if it is a newline |
| 189 | + * @group utility |
135 | 190 | */ |
136 | | - public function chomp( $s ) { |
| 191 | + static public function chomp( $s ) { |
137 | 192 | if ( substr( $s, -1 ) === "\n" ) { |
138 | 193 | return substr( $s, 0, -1 ); |
139 | 194 | } |
— | — | @@ -302,7 +357,7 @@ |
303 | 358 | function runTests( $tests ) { |
304 | 359 | $ok = true; |
305 | 360 | |
306 | | - foreach ( $tests as $i => $t ) { |
| 361 | + foreach ( $tests as $t ) { |
307 | 362 | $result = |
308 | 363 | $this->runTest( $t['test'], $t['input'], $t['result'], $t['options'], $t['config'] ); |
309 | 364 | $ok = $ok && $result; |
— | — | @@ -421,13 +476,20 @@ |
422 | 477 | $result = $this->tidy( $result ); |
423 | 478 | } |
424 | 479 | |
425 | | - |
426 | 480 | $this->teardownGlobals(); |
| 481 | + return $this->showTestResult( $desc, $result, $out ); |
| 482 | + } |
427 | 483 | |
428 | | - if ( $result === $out && ( $noxml === true || $this->wellFormed( $out ) ) ) { |
429 | | - return $this->showSuccess( $desc ); |
| 484 | + /** |
| 485 | + * |
| 486 | + */ |
| 487 | + function showTestResult( $desc, $result, $out ) { |
| 488 | + if ( $result === $out ) { |
| 489 | + $this->showSuccess( $desc ); |
| 490 | + return true; |
430 | 491 | } else { |
431 | | - return $this->showFailure( $desc, $result, $out ); |
| 492 | + $this->showFailure( $desc, $result, $out ); |
| 493 | + return false; |
432 | 494 | } |
433 | 495 | } |
434 | 496 | |
— | — | @@ -820,6 +882,7 @@ |
821 | 883 | global $wgDBtype; |
822 | 884 | |
823 | 885 | if ( !$this->databaseSetupDone ) { |
| 886 | + $this->teardownGlobals(); |
824 | 887 | return; |
825 | 888 | } |
826 | 889 | $this->teardownUploadDir( $this->uploadDir ); |
— | — | @@ -829,6 +892,7 @@ |
830 | 893 | |
831 | 894 | if ( $this->useTemporaryTables ) { |
832 | 895 | # Don't need to do anything |
| 896 | + $this->teardownGlobals(); |
833 | 897 | return; |
834 | 898 | } |
835 | 899 | |
— | — | @@ -842,6 +906,8 @@ |
843 | 907 | |
844 | 908 | if ( $wgDBtype == 'oracle' ) |
845 | 909 | $db->query( 'BEGIN FILL_WIKI_INFO; END;' ); |
| 910 | + |
| 911 | + $this->teardownGlobals(); |
846 | 912 | } |
847 | 913 | |
848 | 914 | /** |
— | — | @@ -1085,20 +1151,26 @@ |
1086 | 1152 | * @param $text String: the article text |
1087 | 1153 | * @param $line Integer: the input line number, for reporting errors |
1088 | 1154 | */ |
1089 | | - public function addArticle( $name, $text, $line ) { |
| 1155 | + static public function addArticle( $name, $text, $line ) { |
1090 | 1156 | global $wgCapitalLinks; |
| 1157 | + |
| 1158 | + $text = self::chomp($text); |
| 1159 | + |
1091 | 1160 | $oldCapitalLinks = $wgCapitalLinks; |
1092 | 1161 | $wgCapitalLinks = true; // We only need this from SetupGlobals() See r70917#c8637 |
1093 | 1162 | |
1094 | | - $title = Title::newFromText( $name ); |
| 1163 | + $title = Title::newFromText( self::chomp($name) ); |
1095 | 1164 | |
1096 | 1165 | if ( is_null( $title ) ) { |
1097 | | - wfDie( "invalid title at line $line\n" ); |
| 1166 | + wfDie( "invalid title ('$name' => '$title') at line $line\n" ); |
1098 | 1167 | } |
1099 | 1168 | |
1100 | 1169 | $aid = $title->getArticleID( Title::GAID_FOR_UPDATE ); |
1101 | 1170 | |
1102 | 1171 | if ( $aid != 0 ) { |
| 1172 | + foreach(debug_backtrace() as $bt) { |
| 1173 | + echo "{$bt['file']}::{$bt['line']}\n"; |
| 1174 | + } |
1103 | 1175 | wfDie( "duplicate article '$name' at line $line\n" ); |
1104 | 1176 | } |
1105 | 1177 | |
Index: branches/querypage-work2/phase3/maintenance/tests/RunSeleniumTests.php |
— | — | @@ -5,7 +5,8 @@ |
6 | 6 | * @ingroup Maintenance |
7 | 7 | * @copyright Copyright © Wikimedia Deuschland, 2009 |
8 | 8 | * @author Hallo Welt! Medienwerkstatt GmbH |
9 | | - * @author Markus Glaser, Dan Nessett |
| 9 | + * @author Markus Glaser, Dan Nessett, Priyanka Dhanda |
| 10 | + * initial idea by Daniel Kinzler |
10 | 11 | * |
11 | 12 | * This program is free software; you can redistribute it and/or modify |
12 | 13 | * it under the terms of the GNU General Public License as published by |
— | — | @@ -28,24 +29,29 @@ |
29 | 30 | require_once( dirname( dirname( __FILE__ ) )."/Maintenance.php" ); |
30 | 31 | require_once( 'PHPUnit/Framework.php' ); |
31 | 32 | require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' ); |
| 33 | +require_once( 'PHPUnit/Util/Log/JUnit.php' ); |
| 34 | +require_once( dirname( __FILE__ ) . "/selenium/SeleniumServerManager.php" ); |
32 | 35 | |
33 | | - |
34 | 36 | class SeleniumTester extends Maintenance { |
35 | 37 | protected $selenium; |
| 38 | + protected $serverManager; |
| 39 | + protected $seleniumServerExecPath; |
36 | 40 | |
37 | 41 | public function __construct() { |
38 | 42 | parent::__construct(); |
39 | 43 | $this->mDescription = "Selenium Test Runner. For documentation, visit http://www.mediawiki.org/wiki/SeleniumFramework"; |
40 | | - $this->addOption( 'port', 'Port used by selenium server. Default: 4444' ); |
41 | | - $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath' ); |
42 | | - $this->addOption( 'testBrowser', 'The browser he used during testing. Default: firefox' ); |
43 | | - $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost' ); |
44 | | - $this->addOption( 'username', 'The login username for sunning tests. Default: empty' ); |
45 | | - $this->addOption( 'userPassword', 'The login password for running tests. Default: empty' ); |
46 | | - $this->addOption( 'seleniumConfig', 'Location of the selenium config file. Default: empty' ); |
| 44 | + $this->addOption( 'port', 'Port used by selenium server. Default: 4444', false, true ); |
| 45 | + $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath', false, true ); |
| 46 | + $this->addOption( 'testBrowser', 'The browser used during testing. Default: firefox', false, true ); |
| 47 | + $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost', false, true ); |
| 48 | + $this->addOption( 'username', 'The login username for sunning tests. Default: empty', false, true ); |
| 49 | + $this->addOption( 'userPassword', 'The login password for running tests. Default: empty', false, true ); |
| 50 | + $this->addOption( 'seleniumConfig', 'Location of the selenium config file. Default: empty', false, true ); |
47 | 51 | $this->addOption( 'list-browsers', 'List the available browsers.' ); |
48 | 52 | $this->addOption( 'verbose', 'Be noisier.' ); |
49 | | - |
| 53 | + $this->addOption( 'startserver', 'Start Selenium Server (on localhost) before the run.' ); |
| 54 | + $this->addOption( 'stopserver', 'Stop Selenium Server (on localhost) after the run.' ); |
| 55 | + $this->addOption( 'jUnitLogFile', 'Log results in a specified JUnit log file.', false, true ); |
50 | 56 | $this->deleteOption( 'dbpass' ); |
51 | 57 | $this->deleteOption( 'dbuser' ); |
52 | 58 | $this->deleteOption( 'globals' ); |
— | — | @@ -62,13 +68,59 @@ |
63 | 69 | echo $desc; |
64 | 70 | } |
65 | 71 | |
| 72 | + protected function startServer() { |
| 73 | + if ( $this->seleniumServerExecPath == '' ) { |
| 74 | + die ( "The selenium server exec path is not set in " . |
| 75 | + "selenium_settings.ini. Cannot start server \n" . |
| 76 | + "as requested - terminating RunSeleniumTests\n" ); |
| 77 | + } |
| 78 | + $this->serverManager = new SeleniumServerManager( 'true', |
| 79 | + $this->selenium->getPort(), |
| 80 | + $this->seleniumServerExecPath ); |
| 81 | + switch ( $this->serverManager->start() ) { |
| 82 | + case 'started': |
| 83 | + break; |
| 84 | + case 'failed': |
| 85 | + die ( "Unable to start the Selenium Server - " . |
| 86 | + "terminating RunSeleniumTests\n" ); |
| 87 | + case 'running': |
| 88 | + echo ( "Warning: The Selenium Server is " . |
| 89 | + "already running\n" ); |
| 90 | + break; |
| 91 | + } |
| 92 | + |
| 93 | + return; |
| 94 | + } |
| 95 | + |
| 96 | + protected function stopServer() { |
| 97 | + if ( !isset ( $this->serverManager ) ) { |
| 98 | + echo ( "Warning: Request to stop Selenium Server, but it was " . |
| 99 | + "not stared by RunSeleniumTests\n" . |
| 100 | + "RunSeleniumTests cannot stop a Selenium Server it " . |
| 101 | + "did not start\n" ); |
| 102 | + } else { |
| 103 | + switch ( $this->serverManager->stop() ) { |
| 104 | + case 'stopped': |
| 105 | + break; |
| 106 | + case 'failed': |
| 107 | + echo ( "unable to stop the Selenium Server\n" ); |
| 108 | + } |
| 109 | + } |
| 110 | + return; |
| 111 | + } |
| 112 | + |
66 | 113 | protected function runTests( $seleniumTestSuites = array() ) { |
67 | 114 | $result = new PHPUnit_Framework_TestResult; |
68 | 115 | $result->addListener( new SeleniumTestListener( $this->selenium->getLogger() ) ); |
| 116 | + if ( $this->selenium->getJUnitLogFile() ) { |
| 117 | + $jUnitListener = new PHPUnit_Util_Log_JUnit( $this->selenium->getJUnitLogFile(), true ); |
| 118 | + $result->addListener( $jUnitListener ); |
| 119 | + } |
69 | 120 | |
70 | 121 | foreach ( $seleniumTestSuites as $testSuiteName => $testSuiteFile ) { |
71 | | - require( $testSuiteFile ); |
| 122 | + require( $testSuiteFile ); |
72 | 123 | $suite = new $testSuiteName(); |
| 124 | + $suite->setName( $testSuiteName ); |
73 | 125 | $suite->addTests(); |
74 | 126 | |
75 | 127 | try { |
— | — | @@ -78,6 +130,10 @@ |
79 | 131 | throw new MWException( $e->getMessage() ); |
80 | 132 | } |
81 | 133 | } |
| 134 | + |
| 135 | + if ( $this->selenium->getJUnitLogFile() ) { |
| 136 | + $jUnitListener->flush(); |
| 137 | + } |
82 | 138 | } |
83 | 139 | |
84 | 140 | public function execute() { |
— | — | @@ -107,6 +163,13 @@ |
108 | 164 | $seleniumTestSuites ) ); |
109 | 165 | } |
110 | 166 | |
| 167 | + // State for starting/stopping the Selenium server has nothing to do with the Selenium |
| 168 | + // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but |
| 169 | + // the Maintenance class does not have a setOption() |
| 170 | + if ( isset( $seleniumSettings['startserver'] ) ) $this->getOption( 'startserver', true ); |
| 171 | + if ( isset( $seleniumSettings['stopserver'] ) ) $this->getOption( 'stopserver', true ); |
| 172 | + if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) $seleniumSettings['seleniumserverexecpath'] = ''; |
| 173 | + $this->seleniumServerExecPath = $seleniumSettings['seleniumserverexecpath']; |
111 | 174 | |
112 | 175 | //set reasonable defaults if we did not find the settings |
113 | 176 | if ( !isset( $seleniumBrowsers ) ) $seleniumBrowsers = array ('firefox' => '*firefox'); |
— | — | @@ -116,7 +179,9 @@ |
117 | 180 | if ( !isset( $seleniumSettings['username'] ) ) $seleniumSettings['username'] = ''; |
118 | 181 | if ( !isset( $seleniumSettings['userPassword'] ) ) $seleniumSettings['userPassword'] = ''; |
119 | 182 | if ( !isset( $seleniumSettings['testBrowser'] ) ) $seleniumSettings['testBrowser'] = 'firefox'; |
120 | | - |
| 183 | + if ( !isset( $seleniumSettings['jUnitLogFile'] ) ) $seleniumSettings['jUnitLogFile'] = false; |
| 184 | + |
| 185 | + // Setup Selenium class |
121 | 186 | $this->selenium = new Selenium( ); |
122 | 187 | $this->selenium->setAvailableBrowsers( $seleniumBrowsers ); |
123 | 188 | $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) ); |
— | — | @@ -126,16 +191,24 @@ |
127 | 192 | $this->selenium->setUser( $this->getOption( 'username', $seleniumSettings['username'] ) ); |
128 | 193 | $this->selenium->setPass( $this->getOption( 'userPassword', $seleniumSettings['userPassword'] ) ); |
129 | 194 | $this->selenium->setVerbose( $this->hasOption( 'verbose' ) ); |
| 195 | + $this->selenium->setJUnitLogFile( $this->getOption( 'jUnitLogFile', $seleniumSettings['jUnitLogFile'] ) ); |
130 | 196 | |
131 | 197 | if( $this->hasOption( 'list-browsers' ) ) { |
132 | 198 | $this->listBrowsers(); |
133 | 199 | exit(0); |
134 | 200 | } |
| 201 | + if ( $this->hasOption( 'startserver' ) ) { |
| 202 | + $this->startServer(); |
| 203 | + } |
135 | 204 | |
136 | 205 | $logger = new SeleniumTestConsoleLogger; |
137 | 206 | $this->selenium->setLogger( $logger ); |
138 | 207 | |
139 | 208 | $this->runTests( $seleniumTestSuites ); |
| 209 | + |
| 210 | + if ( $this->hasOption( 'stopserver' ) ) { |
| 211 | + $this->stopServer(); |
| 212 | + } |
140 | 213 | } |
141 | 214 | } |
142 | 215 | |
Property changes on: branches/querypage-work2/phase3/maintenance/tests |
___________________________________________________________________ |
Modified: svn:mergeinfo |
143 | 216 | Merged /trunk/phase3/maintenance/tests:r74568,74575,74577-74581,74584-74585,74587,74589,74591,74595-74596,74606-74607,74614,74625,74627-74628,74643,74646,74677,74679,74681-74684,74686,74688,74691-74692,74695,74697,74703-74704,74725,74727,74731,74740,74742-74750,74752-74753,74755,74771,74778,74780,74784,74786-74787,74789-74790,74792,74795-74798,74800,74804,74806,74810,74820-74822,74824-74825,74827,74831-74832,74836-74837,74841,74843,74847,74849-74851,74855,74859,74884,74891,74896,74898-74899,74901-74902,74904,74910-74914,74918-74920,74922,74932,74934,74943-74957,74959,74962,74964,74966,74969,74975,74978,74981,74988,75002-75003,75006,75018-75019,75021-75022,75024-75025,75029-75031,75035-75037,75040,75054-75057,75059-75061,75064,75066,75068,75083-75084,75087-75088,75096,75098,75100,75102 |
Index: branches/querypage-work2/phase3/maintenance/patchSql.php |
— | — | @@ -39,8 +39,8 @@ |
40 | 40 | foreach ( $this->mArgs as $arg ) { |
41 | 41 | $files = array( |
42 | 42 | $arg, |
43 | | - DatabaseBase::patchPath( $arg ), |
44 | | - DatabaseBase::patchPath( "patch-$arg.sql" ), |
| 43 | + $dbw->patchPath( $arg ), |
| 44 | + $dbw->patchPath( "patch-$arg.sql" ), |
45 | 45 | ); |
46 | 46 | foreach ( $files as $file ) { |
47 | 47 | if ( file_exists( $file ) ) { |
Property changes on: branches/querypage-work2/phase3/maintenance/cleanupTable.inc |
___________________________________________________________________ |
Modified: svn:mergeinfo |
48 | 48 | Merged /trunk/phase3/maintenance/cleanupTable.inc:r74568,74575,74577-74581,74584-74585,74587,74589,74591,74595-74596,74606-74607,74614,74625,74627-74628,74643,74646,74677,74679,74681-74684,74686,74688,74691-74692,74695,74697,74703-74704,74725,74727,74731,74740,74742-74750,74752-74753,74755,74771,74778,74780,74784,74786-74787,74789-74790,74792,74795-74798,74800,74804,74806,74810,74820-74822,74824-74825,74827,74831-74832,74836-74837,74841,74843,74847,74849-74851,74855,74859,74884,74891,74896,74898-74899,74901-74902,74904,74910-74914,74918-74920,74922,74932,74934,74943-74957,74959,74962,74964,74966,74969,74975,74978,74981,74988,75002-75003,75006,75018-75019,75021-75022,75024-75025,75029-75031,75035-75037,75040,75054-75057,75059-75061,75064,75066,75068,75083-75084,75087-75088,75096,75098,75100,75102 |
Index: branches/querypage-work2/phase3/maintenance/rollbackEdits.php |
— | — | @@ -86,7 +86,7 @@ |
87 | 87 | array( 'page_latest = rev_id', 'rev_user_text' => $user ), |
88 | 88 | __METHOD__ |
89 | 89 | ); |
90 | | - while ( $row = $dbr->fetchObject( $results ) ) { |
| 90 | + foreach ( $results as $row ) { |
91 | 91 | $titles[] = Title::makeTitle( $row->page_namespace, $row->page_title ); |
92 | 92 | } |
93 | 93 | return $titles; |
Index: branches/querypage-work2/phase3/maintenance/update.php |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | */ |
12 | 12 | |
13 | 13 | $wgUseMasterForMaintenance = true; |
14 | | -require_once( 'Maintenance.php' ); |
| 14 | +require_once( dirname( __FILE__ ) . '/Maintenance.php' ); |
15 | 15 | |
16 | 16 | class UpdateMediaWiki extends Maintenance { |
17 | 17 | |
Index: branches/querypage-work2/phase3/maintenance/gearman/gearman.inc |
— | — | @@ -72,7 +72,7 @@ |
73 | 73 | if (isset($resp['data']['arg']) && |
74 | 74 | Net_Gearman_Connection::stringLength($resp['data']['arg'])) { |
75 | 75 | $arg = json_decode($resp['data']['arg'], true); |
76 | | - } |
| 76 | + } |
77 | 77 | |
78 | 78 | ### START MW DIFFERENT BIT |
79 | 79 | if ( $name != 'mw_job' ) { |
Index: branches/querypage-work2/phase3/maintenance/language/checkLanguage.inc |
— | — | @@ -444,8 +444,8 @@ |
445 | 445 | * @return True if there are any results, false if not. |
446 | 446 | */ |
447 | 447 | protected function isEmpty() { |
448 | | - foreach( $this->results as $code => $results ) { |
449 | | - foreach( $results as $check => $messages ) { |
| 448 | + foreach( $this->results as $results ) { |
| 449 | + foreach( $results as $messages ) { |
450 | 450 | if( !empty( $messages ) ) { |
451 | 451 | return false; |
452 | 452 | } |
Index: branches/querypage-work2/phase3/maintenance/language/countMessages.php |
— | — | @@ -38,7 +38,7 @@ |
39 | 39 | if ( !preg_match( '/Messages([A-Z][a-z_]+)\.php$/', $baseName, $m ) ) { |
40 | 40 | continue; |
41 | 41 | } |
42 | | - $code = str_replace( '_', '-', strtolower( $m[1] ) ); |
| 42 | + |
43 | 43 | $numMessages = $this->getNumMessages( $file ); |
44 | 44 | // print "$code: $numMessages\n"; |
45 | 45 | $total += $numMessages; |
Index: branches/querypage-work2/phase3/maintenance/userDupes.inc |
— | — | @@ -190,7 +190,7 @@ |
191 | 191 | HAVING n > 1", $fname ); |
192 | 192 | |
193 | 193 | $list = array(); |
194 | | - while ( $row = $this->db->fetchObject( $result ) ) { |
| 194 | + foreach ( $result as $row ) { |
195 | 195 | $list[] = $row->user_name; |
196 | 196 | } |
197 | 197 | return $list; |
— | — | @@ -215,7 +215,7 @@ |
216 | 216 | $firstId = $firstRow->user_id; |
217 | 217 | wfOut( "Record that will be used for '$name' is user_id=$firstId\n" ); |
218 | 218 | |
219 | | - while ( $row = $this->db->fetchObject( $result ) ) { |
| 219 | + foreach ( $result as $row ) { |
220 | 220 | $dupeId = $row->user_id; |
221 | 221 | wfOut( "... dupe id $dupeId: " ); |
222 | 222 | $edits = $this->editCount( $dupeId ); |
Index: branches/querypage-work2/phase3/maintenance/lag.php |
— | — | @@ -30,7 +30,7 @@ |
31 | 31 | $lags = $lb->getLagTimes(); |
32 | 32 | unset( $lags[0] ); |
33 | 33 | echo gmdate( 'H:i:s' ) . ' '; |
34 | | - foreach ( $lags as $i => $lag ) { |
| 34 | + foreach ( $lags as $lag ) { |
35 | 35 | printf( "%-12s " , $lag === false ? 'false' : $lag ); |
36 | 36 | } |
37 | 37 | echo "\n"; |
Index: branches/querypage-work2/phase3/maintenance/doMaintenance.php |
— | — | @@ -67,6 +67,7 @@ |
68 | 68 | require_once( "$IP/includes/DefaultSettings.php" ); |
69 | 69 | |
70 | 70 | $callback = MW_CONFIG_CALLBACK; |
| 71 | + # PHP 5.1 doesn't support "class::method" for call_user_func, so split it |
71 | 72 | if ( strpos( $callback, '::' ) !== false ) { |
72 | 73 | $callback = explode( '::', $callback, 2); |
73 | 74 | } |
Index: branches/querypage-work2/phase3/maintenance/storage/compressOld.inc |
— | — | @@ -18,7 +18,7 @@ |
19 | 19 | break; |
20 | 20 | } |
21 | 21 | $last = $start; |
22 | | - while( $row = $dbw->fetchObject( $res ) ) { |
| 22 | + foreach ( $res as $row ) { |
23 | 23 | # print " {$row->old_id} - {$row->old_namespace}:{$row->old_title}\n"; |
24 | 24 | compressPage( $row, $extdb ); |
25 | 25 | $last = $row->old_id; |
— | — | @@ -169,7 +169,7 @@ |
170 | 170 | $revLoadOptions |
171 | 171 | ); |
172 | 172 | $revs = array(); |
173 | | - while ( $revRow = $dbw->fetchObject( $revRes ) ) { |
| 173 | + foreach ( $revRes as $revRow ) { |
174 | 174 | $revs[] = $revRow; |
175 | 175 | } |
176 | 176 | |
Index: branches/querypage-work2/phase3/maintenance/storage/moveToExternal.php |
— | — | @@ -59,7 +59,7 @@ |
60 | 60 | "old_id BETWEEN $blockStart AND $blockEnd", |
61 | 61 | 'old_flags NOT ' . $dbr->buildLike( $dbr->anyString(), 'external', $dbr->anyString() ), |
62 | 62 | ), $fname ); |
63 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 63 | + foreach ( $res as $row ) { |
64 | 64 | # Resolve stubs |
65 | 65 | $text = $row->old_text; |
66 | 66 | $id = $row->old_id; |
Index: branches/querypage-work2/phase3/maintenance/storage/resolveStubs.php |
— | — | @@ -38,7 +38,7 @@ |
39 | 39 | "AND old_flags LIKE '%object%' AND old_flags NOT LIKE '%external%' " . |
40 | 40 | 'AND LOWER(CONVERT(LEFT(old_text,22) USING latin1)) = \'o:15:"historyblobstub"\'', |
41 | 41 | $fname ); |
42 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 42 | + foreach ( $res as $row ) { |
43 | 43 | resolveStub( $row->old_id, $row->old_text, $row->old_flags ); |
44 | 44 | } |
45 | 45 | } |
Index: branches/querypage-work2/phase3/maintenance/storage/checkStorage.php |
— | — | @@ -70,7 +70,7 @@ |
71 | 71 | $dbr->ping(); |
72 | 72 | $res = $dbr->select( 'revision', array( 'rev_id', 'rev_text_id' ), |
73 | 73 | array( "rev_id BETWEEN $chunkStart AND $chunkEnd" ), $fname ); |
74 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 74 | + foreach ( $res as $row ) { |
75 | 75 | $this->oldIdMap[$row->rev_id] = $row->rev_text_id; |
76 | 76 | } |
77 | 77 | $dbr->freeResult( $res ); |
— | — | @@ -85,7 +85,7 @@ |
86 | 86 | $objectRevs = array(); |
87 | 87 | $res = $dbr->select( 'text', array( 'old_id', 'old_flags' ), |
88 | 88 | 'old_id IN (' . implode( ',', $this->oldIdMap ) . ')', $fname ); |
89 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 89 | + foreach ( $res as $row ) { |
90 | 90 | $flags = $row->old_flags; |
91 | 91 | $id = $row->old_id; |
92 | 92 | |
— | — | @@ -139,7 +139,7 @@ |
140 | 140 | if ( count( $externalRevs ) ) { |
141 | 141 | $res = $dbr->select( 'text', array( 'old_id', 'old_flags', 'old_text' ), |
142 | 142 | array( 'old_id IN (' . implode( ',', $externalRevs ) . ')' ), $fname ); |
143 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 143 | + foreach ( $res as $row ) { |
144 | 144 | $urlParts = explode( '://', $row->old_text, 2 ); |
145 | 145 | if ( count( $urlParts ) !== 2 || $urlParts[1] == '' ) { |
146 | 146 | $this->error( 'restore text', "Error: invalid URL \"{$row->old_text}\"", $row->old_id ); |
— | — | @@ -177,7 +177,7 @@ |
178 | 178 | $res = $extDb->select( $blobsTable, |
179 | 179 | array( 'blob_id' ), |
180 | 180 | array( 'blob_id IN( ' . implode( ',', $blobIds ) . ')' ), $fname ); |
181 | | - while ( $row = $extDb->fetchObject( $res ) ) { |
| 181 | + foreach ( $res as $row ) { |
182 | 182 | unset( $xBlobIds[$row->blob_id] ); |
183 | 183 | } |
184 | 184 | $extDb->freeResult( $res ); |
— | — | @@ -196,7 +196,7 @@ |
197 | 197 | $headerLength = 300; |
198 | 198 | $res = $dbr->select( 'text', array( 'old_id', 'old_flags', "LEFT(old_text, $headerLength) AS header" ), |
199 | 199 | array( 'old_id IN (' . implode( ',', $objectRevs ) . ')' ), $fname ); |
200 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 200 | + foreach ( $res as $row ) { |
201 | 201 | $oldId = $row->old_id; |
202 | 202 | $matches = array(); |
203 | 203 | if ( !preg_match( '/^O:(\d+):"(\w+)"/', $row->header, $matches ) ) { |
— | — | @@ -247,7 +247,7 @@ |
248 | 248 | $headerLength = 300; |
249 | 249 | $res = $dbr->select( 'text', array( 'old_id', 'old_flags', "LEFT(old_text, $headerLength) AS header" ), |
250 | 250 | array( 'old_id IN (' . implode( ',', array_keys( $concatBlobs ) ) . ')' ), $fname ); |
251 | | - while ( $row = $dbr->fetchObject( $res ) ) { |
| 251 | + foreach ( $res as $row ) { |
252 | 252 | $flags = explode( ',', $row->old_flags ); |
253 | 253 | if ( in_array( 'external', $flags ) ) { |
254 | 254 | // Concat blob is in external storage? |
— | — | @@ -355,7 +355,7 @@ |
356 | 356 | $res = $extDb->select( $blobsTable, |
357 | 357 | array( 'blob_id', "LEFT(blob_text, $headerLength) AS header" ), |
358 | 358 | array( 'blob_id IN( ' . implode( ',', $blobIds ) . ')' ), $fname ); |
359 | | - while ( $row = $extDb->fetchObject( $res ) ) { |
| 359 | + foreach ( $res as $row ) { |
360 | 360 | if ( strcasecmp( $row->header, CONCAT_HEADER ) ) { |
361 | 361 | $this->error( 'restore text', "Error: invalid header on target $cluster/{$row->blob_id} of two-part ES URL", |
362 | 362 | $oldIds[$row->blob_id] ); |
Index: branches/querypage-work2/phase3/maintenance/nextJobDB.php |
— | — | @@ -64,7 +64,7 @@ |
65 | 65 | $dbsByMaster[$lb->getServerName( 0 )][] = $db; |
66 | 66 | } |
67 | 67 | |
68 | | - foreach ( $dbsByMaster as $master => $dbs ) { |
| 68 | + foreach ( $dbsByMaster as $dbs ) { |
69 | 69 | $dbConn = wfGetDB( DB_MASTER, array(), $dbs[0] ); |
70 | 70 | $stype = $dbConn->addQuotes( $type ); |
71 | 71 | |
Index: branches/querypage-work2/phase3/maintenance/oracle/tables.sql |
— | — | @@ -127,8 +127,8 @@ |
128 | 128 | ); |
129 | 129 | CREATE INDEX &mw_prefix.archive_i01 ON &mw_prefix.archive (ar_namespace,ar_title,ar_timestamp); |
130 | 130 | CREATE INDEX &mw_prefix.archive_i02 ON &mw_prefix.archive (ar_user_text,ar_timestamp); |
| 131 | +CREATE INDEX &mw_prefix.archive_i03 ON &mw_prefix.archive (ar_namespace, ar_title, ar_rev_id); |
131 | 132 | |
132 | | - |
133 | 133 | CREATE TABLE &mw_prefix.pagelinks ( |
134 | 134 | pl_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE, |
135 | 135 | pl_namespace NUMBER NOT NULL, |
— | — | @@ -156,12 +156,16 @@ |
157 | 157 | CREATE TABLE &mw_prefix.categorylinks ( |
158 | 158 | cl_from NUMBER NOT NULL REFERENCES &mw_prefix.page(page_id) ON DELETE CASCADE, |
159 | 159 | cl_to VARCHAR2(255) NOT NULL, |
160 | | - cl_sortkey VARCHAR2(255), |
161 | | - cl_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL |
| 160 | + cl_sortkey VARCHAR2(230), |
| 161 | + cl_sortkey_prefix VARCHAR2(255) DEFAULT '' NOT NULL, |
| 162 | + cl_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL, |
| 163 | + cl_collation VARCHAR2(32) DEFAULT '' NOT NULL, |
| 164 | + cl_type VARCHAR2(6) DEFAULT 'page' NOT NULL |
162 | 165 | ); |
163 | 166 | CREATE UNIQUE INDEX &mw_prefix.categorylinks_u01 ON &mw_prefix.categorylinks (cl_from,cl_to); |
164 | | -CREATE INDEX &mw_prefix.categorylinks_i01 ON &mw_prefix.categorylinks (cl_to,cl_sortkey,cl_from); |
| 167 | +CREATE INDEX &mw_prefix.categorylinks_i01 ON &mw_prefix.categorylinks (cl_to,cl_type,cl_sortkey,cl_from); |
165 | 168 | CREATE INDEX &mw_prefix.categorylinks_i02 ON &mw_prefix.categorylinks (cl_to,cl_timestamp); |
| 169 | +CREATE INDEX &mw_prefix.categorylinks_i03 ON &mw_prefix.categorylinks (cl_collation); |
166 | 170 | |
167 | 171 | CREATE SEQUENCE category_cat_id_seq; |
168 | 172 | CREATE TABLE &mw_prefix.category ( |
— | — | @@ -200,6 +204,14 @@ |
201 | 205 | CREATE UNIQUE INDEX &mw_prefix.langlinks_u01 ON &mw_prefix.langlinks (ll_from, ll_lang); |
202 | 206 | CREATE INDEX &mw_prefix.langlinks_i01 ON &mw_prefix.langlinks (ll_lang, ll_title); |
203 | 207 | |
| 208 | +CREATE TABLE &mw_prefix.iwlinks ( |
| 209 | + iwl_from NUMBER DEFAULT 0 NOT NULL, |
| 210 | + iwl_prefix VARCHAR2(20) DEFAULT '' NOT NULL, |
| 211 | + iwl_title VARCHAR2(255) DEFAULT '' NOT NULL |
| 212 | +); |
| 213 | +CREATE UNIQUE INDEX &mw_prefix.iwlinks_ui01 ON &mw_prefix.iwlinks (iwl_from, iwl_prefix, iwl_title); |
| 214 | +CREATE UNIQUE INDEX &mw_prefix.iwlinks_ui02 ON &mw_prefix.iwlinks (iwl_prefix, iwl_title, iwl_from); |
| 215 | + |
204 | 216 | CREATE TABLE &mw_prefix.site_stats ( |
205 | 217 | ss_row_id NUMBER NOT NULL , |
206 | 218 | ss_total_views NUMBER DEFAULT 0, |
— | — | @@ -388,6 +400,8 @@ |
389 | 401 | CREATE TABLE &mw_prefix.interwiki ( |
390 | 402 | iw_prefix VARCHAR2(32) NOT NULL, |
391 | 403 | iw_url VARCHAR2(127) NOT NULL, |
| 404 | + iw_api BLOB NOT NULL, |
| 405 | + iw_wikiid VARCHAR2(64), |
392 | 406 | iw_local CHAR(1) NOT NULL, |
393 | 407 | iw_trans CHAR(1) DEFAULT '0' NOT NULL |
394 | 408 | ); |
— | — | @@ -531,7 +545,8 @@ |
532 | 546 | |
533 | 547 | |
534 | 548 | CREATE TABLE &mw_prefix.updatelog ( |
535 | | - ul_key VARCHAR2(255) NOT NULL |
| 549 | + ul_key VARCHAR2(255) NOT NULL, |
| 550 | + ul_value BLOB |
536 | 551 | ); |
537 | 552 | ALTER TABLE &mw_prefix.updatelog ADD CONSTRAINT &mw_prefix.updatelog_pk PRIMARY KEY (ul_key); |
538 | 553 | |
— | — | @@ -581,6 +596,27 @@ |
582 | 597 | ); |
583 | 598 | CREATE INDEX &mw_prefix.l10n_cache_u01 ON &mw_prefix.l10n_cache (lc_lang, lc_key); |
584 | 599 | |
| 600 | +CREATE TABLE &mw_prefix.msg_resource ( |
| 601 | + mr_resource VARCHAR2(255) NOT NULL, |
| 602 | + mr_lang varchar2(32) NOT NULL, |
| 603 | + mr_blob BLOB NOT NULL, |
| 604 | + mr_timestamp TIMESTAMP(6) WITH TIME ZONE NOT NULL |
| 605 | +) ; |
| 606 | +CREATE UNIQUE INDEX &mw_prefix.msg_resource_u01 ON &mw_prefix.msg_resource (mr_resource, mr_lang); |
| 607 | + |
| 608 | +CREATE TABLE &mw_prefix.msg_resource_links ( |
| 609 | + mrl_resource VARCHAR2(255) NOT NULL, |
| 610 | + mrl_message VARCHAR2(255) NOT NULL |
| 611 | +); |
| 612 | +CREATE UNIQUE INDEX &mw_prefix.msg_resource_links_u01 ON &mw_prefix.msg_resource_links (mrl_message, mrl_resource); |
| 613 | + |
| 614 | +CREATE TABLE &mw_prefix.module_deps ( |
| 615 | + md_module VARCHAR2(255) NOT NULL, |
| 616 | + md_skin VARCHAR2(32) NOT NULL, |
| 617 | + md_deps BLOB NOT NULL |
| 618 | +); |
| 619 | +CREATE UNIQUE INDEX &mw_prefix.module_deps_u01 ON &mw_prefix.module_deps (md_module, md_skin); |
| 620 | + |
585 | 621 | -- do not prefix this table as it breaks parserTests |
586 | 622 | CREATE TABLE wiki_field_info_full ( |
587 | 623 | table_name VARCHAR2(35) NOT NULL, |
Index: branches/querypage-work2/phase3/maintenance/oracle/user.sql |
— | — | @@ -1,8 +1,8 @@ |
2 | 2 | -- defines must comply with ^define\s*([^\s=]*)\s*=\s?'\{\$([^\}]*)\}'; |
3 | 3 | define wiki_user='{$wgDBuser}'; |
4 | 4 | define wiki_pass='{$wgDBpassword}'; |
5 | | -define def_ts='{$wgDBOracleDefTS}'; |
6 | | -define temp_ts='{$wgDBOracleTempTS}'; |
| 5 | +define def_ts='{$_OracleDefTS}'; |
| 6 | +define temp_ts='{$_OracleTempTS}'; |
7 | 7 | |
8 | 8 | create user &wiki_user. identified by &wiki_pass. default tablespace &def_ts. temporary tablespace &temp_ts. quota unlimited on &def_ts.; |
9 | 9 | grant connect, resource to &wiki_user.; |
Index: branches/querypage-work2/phase3/maintenance/convertLinks.php |
— | — | @@ -113,7 +113,7 @@ |
114 | 114 | $res = $dbw->query( "SELECT cur_namespace,cur_title,cur_id FROM $cur" ); |
115 | 115 | $ids = array(); |
116 | 116 | |
117 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
| 117 | + foreach ( $res as $row ) { |
118 | 118 | $title = $row->cur_title; |
119 | 119 | if ( $row->cur_namespace ) { |
120 | 120 | $title = $wgContLang->getNsText( $row->cur_namespace ) . ":$title"; |
— | — | @@ -154,7 +154,7 @@ |
155 | 155 | } |
156 | 156 | |
157 | 157 | $tuplesAdded = 0; # no tuples added to INSERT yet |
158 | | - while ( $row = $dbw->fetchObject( $res ) ) { |
| 158 | + foreach ( $res as $row ) { |
159 | 159 | $fromTitle = $row->l_from; |
160 | 160 | if ( array_key_exists( $fromTitle, $ids ) ) { # valid title |
161 | 161 | $from = $ids[$fromTitle]; |
Index: branches/querypage-work2/phase3/maintenance/deleteSelfExternals.php |
— | — | @@ -24,7 +24,7 @@ |
25 | 25 | * @ingroup Maintenance |
26 | 26 | */ |
27 | 27 | |
28 | | -require_once( "Maintenance.php" ); |
| 28 | +require_once( dirname( __FILE__ ) . '/Maintenance.php' ); |
29 | 29 | |
30 | 30 | |
31 | 31 | class DeleteSelfExternals extends Maintenance { |
— | — | @@ -45,7 +45,7 @@ |
46 | 46 | . $db->buildLike( $wgServer . '/', $db->anyString() ), $this->mBatchSize ); |
47 | 47 | $this->output( "Deleting a batch\n" ); |
48 | 48 | $db->query( $q ); |
49 | | - if ( !$db->affectedRows() ) exit( 0 ); |
| 49 | + if ( !$db->affectedRows() ) return; |
50 | 50 | } |
51 | 51 | } |
52 | 52 | } |
Property changes on: branches/querypage-work2/phase3/maintenance/deleteSelfExternals.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
53 | 53 | Merged /trunk/phase3/maintenance/deleteSelfExternals.php:r74568,74575,74577-74581,74584-74585,74587,74589,74591,74595-74596,74606-74607,74614,74625,74627-74628,74643,74646,74677,74679,74681-74684,74686,74688,74691-74692,74695,74697,74703-74704,74725,74727,74731,74740,74742-74750,74752-74753,74755,74771,74778,74780,74784,74786-74787,74789-74790,74792,74795-74798,74800,74804,74806,74810,74820-74822,74824-74825,74827,74831-74832,74836-74837,74841,74843,74847,74849-74851,74855,74859,74884,74891,74896,74898-74899,74901-74902,74904,74910-74914,74918-74920,74922,74932,74934,74943-74957,74959,74962,74964,74966,74969,74975,74978,74981,74988,75002-75003,75006,75018-75019,75021-75022,75024-75025,75029-75031,75035-75037,75040,75054-75057,75059-75061,75064,75066,75068,75083-75084,75087-75088,75096,75098,75100,75102 |
Property changes on: branches/querypage-work2/phase3/maintenance/populateRevisionLength.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
54 | 54 | Merged /trunk/phase3/maintenance/populateRevisionLength.php:r74568,74575,74577-74581,74584-74585,74587,74589,74591,74595-74596,74606-74607,74614,74625,74627-74628,74643,74646,74677,74679,74681-74684,74686,74688,74691-74692,74695,74697,74703-74704,74725,74727,74731,74740,74742-74750,74752-74753,74755,74771,74778,74780,74784,74786-74787,74789-74790,74792,74795-74798,74800,74804,74806,74810,74820-74822,74824-74825,74827,74831-74832,74836-74837,74841,74843,74847,74849-74851,74855,74859,74884,74891,74896,74898-74899,74901-74902,74904,74910-74914,74918-74920,74922,74932,74934,74943-74957,74959,74962,74964,74966,74969,74975,74978,74981,74988,75002-75003,75006,75018-75019,75021-75022,75024-75025,75029-75031,75035-75037,75040,75054-75057,75059-75061,75064,75066,75068,75083-75084,75087-75088,75096,75098,75100,75102 |
Index: branches/querypage-work2/phase3/maintenance/userOptions.inc |
— | — | @@ -111,7 +111,7 @@ |
112 | 112 | __METHOD__ |
113 | 113 | ); |
114 | 114 | |
115 | | - while ( $id = $dbr->fetchObject( $result ) ) { |
| 115 | + foreach ( $result as $id ) { |
116 | 116 | |
117 | 117 | $user = User::newFromId( $id->user_id ); |
118 | 118 | |
— | — | @@ -161,7 +161,7 @@ |
162 | 162 | __METHOD__ |
163 | 163 | ); |
164 | 164 | |
165 | | - while ( $id = $dbr->fetchObject( $result ) ) { |
| 165 | + foreach ( $result as $id ) { |
166 | 166 | |
167 | 167 | $user = User::newFromId( $id->user_id ); |
168 | 168 | |
Index: branches/querypage-work2/phase3/maintenance/archives/patch-categorylinks-better-collation.sql |
— | — | @@ -5,7 +5,7 @@ |
6 | 6 | -- changes are also incorporated into patch-categorylinks-better-collation2.sql, |
7 | 7 | -- for the benefit of trunk users who applied the original. |
8 | 8 | ALTER TABLE /*$wgDBprefix*/categorylinks |
9 | | - CHANGE COLUMN cl_sortkey cl_sortkey varbinary(255) NOT NULL default '', |
| 9 | + CHANGE COLUMN cl_sortkey cl_sortkey varbinary(230) NOT NULL default '', |
10 | 10 | ADD COLUMN cl_sortkey_prefix varchar(255) binary NOT NULL default '', |
11 | 11 | ADD COLUMN cl_collation varbinary(32) NOT NULL default '', |
12 | 12 | ADD COLUMN cl_type ENUM('page', 'subcat', 'file') NOT NULL default 'page', |
Index: branches/querypage-work2/phase3/maintenance/archives/patch-categorylinks-better-collation2.sql |
— | — | @@ -7,6 +7,6 @@ |
8 | 8 | -- large table unnecessarily for people upgrading from 1.16, so this will be |
9 | 9 | -- skipped if unneeded. |
10 | 10 | ALTER TABLE /*$wgDBprefix*/categorylinks |
11 | | - CHANGE COLUMN cl_sortkey cl_sortkey varbinary(255) NOT NULL default '', |
| 11 | + CHANGE COLUMN cl_sortkey cl_sortkey varbinary(230) NOT NULL default '', |
12 | 12 | CHANGE COLUMN cl_collation cl_collation varbinary(32) NOT NULL default ''; |
13 | 13 | INSERT IGNORE INTO /*$wgDBprefix*/updatelog (ul_key) VALUES ('cl_fields_update'); |
Property changes on: branches/querypage-work2/phase3/maintenance/archives |
___________________________________________________________________ |
Modified: svn:mergeinfo |
14 | 14 | Merged /trunk/phase3/maintenance/archives:r74568,74575,74577-74581,74584-74585,74587,74589,74591,74595-74596,74606-74607,74614,74625,74627-74628,74643,74646,74677,74679,74681-74684,74686,74688,74691-74692,74695,74697,74703-74704,74725,74727,74731,74740,74742-74750,74752-74753,74755,74771,74778,74780,74784,74786-74787,74789-74790,74792,74795-74798,74800,74804,74806,74810,74820-74822,74824-74825,74827,74831-74832,74836-74837,74841,74843,74847,74849-74851,74855,74859,74884,74891,74896,74898-74899,74901-74902,74904,74910-74914,74918-74920,74922,74932,74934,74943-74957,74959,74962,74964,74966,74969,74975,74978,74981,74988,75002-75003,75006,75018-75019,75021-75022,75024-75025,75029-75031,75035-75037,75040,75054-75057,75059-75061,75064,75066,75068,75083-75084,75087-75088,75096,75098,75100,75102 |
Index: branches/querypage-work2/phase3/maintenance/initEditCount.php |
— | — | @@ -1,5 +1,8 @@ |
2 | 2 | <?php |
3 | 3 | /** |
| 4 | + * Init the user_editcount database field based on the number of rows in the |
| 5 | + * revision table. |
| 6 | + * |
4 | 7 | * This program is free software; you can redistribute it and/or modify |
5 | 8 | * it under the terms of the GNU General Public License as published by |
6 | 9 | * the Free Software Foundation; either version 2 of the License, or |
— | — | @@ -15,6 +18,7 @@ |
16 | 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | 20 | * http://www.gnu.org/copyleft/gpl.html |
18 | 21 | * |
| 22 | + * @file |
19 | 23 | * @ingroup Maintenance |
20 | 24 | */ |
21 | 25 | |
— | — | @@ -30,12 +34,11 @@ |
31 | 35 | |
32 | 36 | Background mode will be automatically used if the server is MySQL 4.0 |
33 | 37 | (which does not support subqueries) or if multiple servers are listed |
34 | | -in $wgDBservers, usually indicating a replication environment.' ); |
| 38 | +in the load balancer, usually indicating a replication environment.' ); |
35 | 39 | $this->mDescription = "Batch-recalculate user_editcount fields from the revision table"; |
36 | 40 | } |
37 | 41 | |
38 | 42 | public function execute() { |
39 | | - global $wgDBservers; |
40 | 43 | $dbw = wfGetDB( DB_MASTER ); |
41 | 44 | $user = $dbw->tableName( 'user' ); |
42 | 45 | $revision = $dbw->tableName( 'revision' ); |
— | — | @@ -43,7 +46,7 @@ |
44 | 47 | $dbver = $dbw->getServerVersion(); |
45 | 48 | |
46 | 49 | // Autodetect mode... |
47 | | - $backgroundMode = count( $wgDBservers ) > 1 || |
| 50 | + $backgroundMode = wfGetLB()->getServerCount() > 1 || |
48 | 51 | ( $dbw instanceof DatabaseMysql && version_compare( $dbver, '4.1' ) < 0 ); |
49 | 52 | |
50 | 53 | if ( $this->hasOption( 'background' ) ) { |
Index: branches/querypage-work2/phase3/maintenance/install-utils.inc |
— | — | @@ -191,7 +191,8 @@ |
192 | 192 | |
193 | 193 | function archive( $name ) { |
194 | 194 | wfDeprecated( __METHOD__ ); |
195 | | - return DatabaseBase::patchPath( $name ); |
| 195 | + $dbr = wfGetDB( DB_SLAVE ); |
| 196 | + return $dbr->patchPath( $name ); |
196 | 197 | } |
197 | 198 | |
198 | 199 | /** |
Index: branches/querypage-work2/phase3/maintenance/renameDbPrefix.php |
— | — | @@ -71,7 +71,7 @@ |
72 | 72 | // sort of message. Best not to try $row->x stuff... |
73 | 73 | $fields = get_object_vars( $row ); |
74 | 74 | // Silly for loop over one field... |
75 | | - foreach ( $fields as $resName => $table ) { |
| 75 | + foreach ( $fields as $table ) { |
76 | 76 | // $old should be regexp safe ([a-zA-Z_]) |
77 | 77 | $newTable = preg_replace( '/^' . $old . '/', $new, $table ); |
78 | 78 | $this->output( "Renaming table $table to $newTable\n" ); |
Index: branches/querypage-work2/phase3/maintenance/dumpInterwiki.php |
— | — | @@ -125,7 +125,7 @@ |
126 | 126 | if ( preg_match( '/^\|\s*(.*?)\s*\|\|\s*(.*?)\s*$/', $line, $matches ) ) { |
127 | 127 | $prefix = $wgContLang->lc( $matches[1] ); |
128 | 128 | $prefix = str_replace( ' ', '_', $prefix ); |
129 | | - $prefix = strtolower( $matches[1] ); |
| 129 | + |
130 | 130 | $url = $matches[2]; |
131 | 131 | if ( preg_match( '/(wikipedia|wiktionary|wikisource|wikiquote|wikibooks|wikimedia)\.org/', $url ) ) { |
132 | 132 | $local = 1; |
— | — | @@ -148,7 +148,6 @@ |
149 | 149 | $this->makeLanguageLinks ( $site, "_" . $site->suffix ); |
150 | 150 | } |
151 | 151 | |
152 | | - |
153 | 152 | foreach ( $dblist as $db ) { |
154 | 153 | if ( isset( $this->specials[$db] ) ) { |
155 | 154 | # Special wiki |
Index: branches/querypage-work2/phase3/maintenance/populateSha1.php |
— | — | @@ -52,7 +52,6 @@ |
53 | 53 | $res = $dbw->select( 'image', array( 'img_name' ), array( 'img_sha1' => '' ), __METHOD__ ); |
54 | 54 | } |
55 | 55 | $imageTable = $dbw->tableName( 'image' ); |
56 | | - $oldimageTable = $dbw->tableName( 'oldimage' ); |
57 | 56 | |
58 | 57 | if ( $method == 'pipe' ) { |
59 | 58 | // @fixme kill this and replace with a second unbuffered DB connection. |