r74753 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r74752‎ | r74753 | r74754 >
Date:00:06, 14 October 2010
Author:mglaser
Status:ok (Comments)
Tags:
Comment:
* start / stop selenium server on Linux
* credits to Dan Nessett
Modified paths:
  • /trunk/phase3/maintenance/tests/RunSeleniumTests.php (modified) (history)
  • /trunk/phase3/maintenance/tests/selenium/Selenium.php (modified) (history)
  • /trunk/phase3/maintenance/tests/selenium/SeleniumConfig.php (modified) (history)
  • /trunk/phase3/maintenance/tests/selenium/SeleniumServerManager.php (added) (history)
  • /trunk/phase3/maintenance/tests/selenium/selenium_settings.ini.php52.sample (modified) (history)
  • /trunk/phase3/maintenance/tests/selenium/selenium_settings.ini.sample (modified) (history)

Diff [purge]

Index: trunk/phase3/maintenance/tests/RunSeleniumTests.php
@@ -29,24 +29,28 @@
3030 require_once( dirname( dirname( __FILE__ ) )."/Maintenance.php" );
3131 require_once( 'PHPUnit/Framework.php' );
3232 require_once( 'PHPUnit/Extensions/SeleniumTestCase.php' );
 33+require_once( dirname( __FILE__ ) . "/selenium/SeleniumServerManager.php" );
3334
3435
3536 class SeleniumTester extends Maintenance {
3637 protected $selenium;
 38+ protected $serverManager;
 39+ protected $seleniumServerExecPath;
3740
3841 public function __construct() {
3942 parent::__construct();
4043 $this->mDescription = "Selenium Test Runner. For documentation, visit http://www.mediawiki.org/wiki/SeleniumFramework";
41 - $this->addOption( 'port', 'Port used by selenium server. Default: 4444' );
42 - $this->addOption( 'host', 'Host selenium server. Default: $wgServer . $wgScriptPath' );
43 - $this->addOption( 'testBrowser', 'The browser he used during testing. Default: firefox' );
44 - $this->addOption( 'wikiUrl', 'The Mediawiki installation to point to. Default: http://localhost' );
45 - $this->addOption( 'username', 'The login username for sunning tests. Default: empty' );
46 - $this->addOption( 'userPassword', 'The login password for running tests. Default: empty' );
47 - $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 );
4851 $this->addOption( 'list-browsers', 'List the available browsers.' );
4952 $this->addOption( 'verbose', 'Be noisier.' );
50 -
 53+ $this->addOption( 'startserver', 'Start Selenium Server (on localhost) before the run.' );
 54+ $this->addOption( 'stopserver', 'Stop Selenium Server (on localhost) after the run.' );
5155 $this->deleteOption( 'dbpass' );
5256 $this->deleteOption( 'dbuser' );
5357 $this->deleteOption( 'globals' );
@@ -63,6 +67,47 @@
6468 echo $desc;
6569 }
6670
 71+ protected function startServer() {
 72+ if ( $this->seleniumServerExecPath == '' ) {
 73+ die ( "The selenium server exec path is not set in " .
 74+ "selenium_settings.ini. Cannot start server \n" .
 75+ "as requested - terminating RunSeleniumTests\n" );
 76+ }
 77+ $this->serverManager = new SeleniumServerManager( 'true',
 78+ $this->selenium->getPort(),
 79+ $this->seleniumServerExecPath );
 80+ switch ( $this->serverManager->start() ) {
 81+ case 'started':
 82+ break;
 83+ case 'failed':
 84+ die ( "Unable to start the Selenium Server - " .
 85+ "terminating RunSeleniumTests\n" );
 86+ case 'running':
 87+ echo ( "Warning: The Selenium Server is " .
 88+ "already running\n" );
 89+ break;
 90+ }
 91+
 92+ return;
 93+ }
 94+
 95+ protected function stopServer() {
 96+ if ( !isset ( $this->serverManager ) ) {
 97+ echo ( "Warning: Request to stop Selenium Server, but it was " .
 98+ "not stared by RunSeleniumTests\n" .
 99+ "RunSeleniumTests cannot stop a Selenium Server it " .
 100+ "did not start\n" );
 101+ } else {
 102+ switch ( $this->serverManager->stop() ) {
 103+ case 'stopped':
 104+ break;
 105+ case 'failed':
 106+ echo ( "unable to stop the Selenium Server\n" );
 107+ }
 108+ }
 109+ return;
 110+ }
 111+
67112 protected function runTests( $seleniumTestSuites = array() ) {
68113 $result = new PHPUnit_Framework_TestResult;
69114 $result->addListener( new SeleniumTestListener( $this->selenium->getLogger() ) );
@@ -108,6 +153,13 @@
109154 $seleniumTestSuites ) );
110155 }
111156
 157+ // State for starting/stopping the Selenium server has nothing to do with the Selenium
 158+ // class. Keep this state local to SeleniumTester class. Using getOption() is clumsy, but
 159+ // the Maintenance class does not have a setOption()
 160+ if ( isset( $seleniumSettings['startserver'] ) ) $this->getOption( 'startserver', true );
 161+ if ( isset( $seleniumSettings['stopserver'] ) ) $this->getOption( 'stopserver', true );
 162+ if ( !isset( $seleniumSettings['seleniumserverexecpath'] ) ) $seleniumSettings['seleniumserverexecpath'] = '';
 163+ $this->seleniumServerExecPath = $seleniumSettings['seleniumserverexecpath'];
112164
113165 //set reasonable defaults if we did not find the settings
114166 if ( !isset( $seleniumBrowsers ) ) $seleniumBrowsers = array ('firefox' => '*firefox');
@@ -117,7 +169,8 @@
118170 if ( !isset( $seleniumSettings['username'] ) ) $seleniumSettings['username'] = '';
119171 if ( !isset( $seleniumSettings['userPassword'] ) ) $seleniumSettings['userPassword'] = '';
120172 if ( !isset( $seleniumSettings['testBrowser'] ) ) $seleniumSettings['testBrowser'] = 'firefox';
121 -
 173+
 174+ // Setup Selenium class
122175 $this->selenium = new Selenium( );
123176 $this->selenium->setAvailableBrowsers( $seleniumBrowsers );
124177 $this->selenium->setUrl( $this->getOption( 'wikiUrl', $seleniumSettings['wikiUrl'] ) );
@@ -132,11 +185,18 @@
133186 $this->listBrowsers();
134187 exit(0);
135188 }
 189+ if ( $this->hasOption( 'startserver' ) ) {
 190+ $this->startServer();
 191+ }
136192
137193 $logger = new SeleniumTestConsoleLogger;
138194 $this->selenium->setLogger( $logger );
139195
140196 $this->runTests( $seleniumTestSuites );
 197+
 198+ if ( $this->hasOption( 'stopserver' ) ) {
 199+ $this->stopServer();
 200+ }
141201 }
142202 }
143203
Index: trunk/phase3/maintenance/tests/selenium/selenium_settings.ini.sample
@@ -9,6 +9,8 @@
1010 username = "wikiuser"
1111 userPassword = "wikipass"
1212 testBrowser = "firefox"
 13+startserver =
 14+stopserver =
1315
1416 [SeleniumTests]
1517
Index: trunk/phase3/maintenance/tests/selenium/Selenium.php
@@ -112,6 +112,10 @@
113113 $this->port = $port;
114114 }
115115
 116+ public function getPort() {
 117+ return $this->port;
 118+ }
 119+
116120 public function setUser( $user ) {
117121 $this->user = $user;
118122 }
Index: trunk/phase3/maintenance/tests/selenium/SeleniumServerManager.php
@@ -0,0 +1,228 @@
 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+ exec("ps -U " . $user . " w | grep -i selenium-server", $output);
 146+
 147+ // Start server. If there is already a server running,
 148+ // return running.
 149+
 150+ if ( isset( $this->SeleniumServerExecPath ) ) {
 151+ $found = 0;
 152+ foreach ( $output as $string ) {
 153+ $found += preg_match(
 154+ '~^(.*)java(.+)-jar(.+)selenium-server~',
 155+ $string );
 156+ }
 157+ if ( $found == 0 ) {
 158+
 159+ // Didn't find the selenium server. Start it up.
 160+ // First set up comamand line suffix.
 161+ // NB: $! is pid of last job run in background
 162+ // The echo guarentees it is put into $op when
 163+ // the exec command is run.
 164+
 165+ $commandSuffix = ' > /dev/null 2>&1'. ' & echo $!';
 166+ $portText = ' -port ' . $this->SeleniumServerPort;
 167+ $command = "java -jar " .
 168+ $this->SeleniumServerExecPath .
 169+ $portText . $commandSuffix;
 170+ exec($command ,$op);
 171+ $pid = (int)$op[0];
 172+ if ( $pid != "" )
 173+ $this->SeleniumServerPid = $pid;
 174+ else {
 175+ $this->SeleniumServerPid = 'NaN';
 176+ // Server start failed.
 177+ return 'failed';
 178+ }
 179+ // Wait for the server to startup and listen
 180+ // on its port. Note: this solution kinda
 181+ // stinks, since it uses a wait loop - dnessett
 182+
 183+ for ( $cnt = 1;
 184+ $cnt <= $this->SeleniumServerStartTimeout;
 185+ $cnt++ ) {
 186+ $fp = @fsockopen ( 'localhost',
 187+ $this->SeleniumServerPort,
 188+ &$errno, &$errstr, 0 );
 189+ if ( !$fp ) {
 190+ sleep( 1 );
 191+ continue;
 192+ // Server start succeeded.
 193+ } else {
 194+ fclose ( $fp );
 195+ return 'started';
 196+ }
 197+ }
 198+ echo ( "Starting Selenium server timed out.\n" );
 199+ return 'failed';
 200+ }
 201+ // server already running.
 202+ else return 'running';
 203+
 204+ }
 205+ // No Server execution path defined.
 206+ return 'failed';
 207+ }
 208+
 209+ private function startServerOnWindows() {
 210+ // Unimplemented.
 211+ return 'failed';
 212+ }
 213+
 214+ private function stopServerOnUnix() {
 215+
 216+ if ( !empty( $this->SeleniumServerPid ) &&
 217+ $this->SeleniumServerPid != 'NaN' ) {
 218+ exec( "kill -9 " . $this->SeleniumServerPid );
 219+ return 'stopped';
 220+ }
 221+ else return 'failed';
 222+ }
 223+
 224+ private function stopServerOnWindows() {
 225+ // Unimplemented.
 226+ return 'failed';
 227+
 228+ }
 229+}
Property changes on: trunk/phase3/maintenance/tests/selenium/SeleniumServerManager.php
___________________________________________________________________
Added: svn:keywords
1230 + LastChangedDate LastChangedBy Revision Id
Index: trunk/phase3/maintenance/tests/selenium/selenium_settings.ini.php52.sample
@@ -12,6 +12,8 @@
1313 username = "Wikiadmin"
1414 userPassword = "Wikiadminpw"
1515 testBrowser = "firefox"
 16+startserver =
 17+stopserver =
1618
1719 [testSuite]
1820
Index: trunk/phase3/maintenance/tests/selenium/SeleniumConfig.php
@@ -44,7 +44,11 @@
4545 $seleniumSettings['wikiUrl'] = $configArray['SeleniumSettings']['wikiUrl'];
4646 $seleniumSettings['username'] = $configArray['SeleniumSettings']['username'];
4747 $seleniumSettings['userPassword'] = $configArray['SeleniumSettings']['userPassword'];
48 - $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+
4953 wfRestoreWarnings();
5054 }
5155 if ( array_key_exists( 'SeleniumTests', $configArray) ) {

Follow-up revisions

RevisionCommit summaryAuthorDate
r75031Follow up r74753, removed pass-by-references and @ operatormglaser19:58, 19 October 2010
r75556r74753, r74755, r75254 added new settings, but didn't update SeleniumConfigur...platonides15:51, 27 October 2010

Comments

#Comment by Platonides (talk | contribs)   17:23, 18 October 2010

PHP Deprecated: Call-time pass-by-reference has been deprecated in ./maintenance/tests/selenium/SeleniumServerManager.php on line 187 PHP Deprecated: Call-time pass-by-reference has been deprecated in ./maintenance/tests/selenium/SeleniumServerManager.php on line 187

Additionally, you shouldn't be using @ in mediawiki to skip errors (see wfSuppressErrors())

#Comment by Mglaser (talk | contribs)   20:00, 19 October 2010

should be ok in r75031

Status & tagging log