4 * Bootstrapping for MediaWiki PHPUnit tests
9 use MediaWiki\MediaWikiServices
;
10 use MediaWiki\Registration\ExtensionRegistry
;
11 use PHPUnit\TextUI\Command
;
13 class PHPUnitMaintClass
{
14 public function setup() {
15 // Set a flag which can be used to detect when other scripts have been entered
16 // through this entry point or not.
17 define( 'MW_PHPUNIT_TEST', true );
19 // Send PHP warnings and errors to stderr instead of stdout.
20 // This aids in diagnosing problems, while keeping messages
21 // out of redirected output.
22 if ( ini_get( 'display_errors' ) ) {
23 ini_set( 'display_errors', 'stderr' );
26 $this->prepareEnvironment();
27 require_once __DIR__
. '/../common/TestSetup.php';
28 TestSetup
::snapshotGlobals();
31 public function prepareEnvironment() {
32 # Disable the memory limit as it's not needed for tests.
33 ini_set( 'memory_limit', -1 );
35 # Set max execution time to 0 (no limit). PHP.net says that
36 # "When running PHP from the command line the default setting is 0."
37 # But sometimes this doesn't seem to be the case.
38 ini_set( 'max_execution_time', 0 );
40 # Turn off output buffering if it's on
41 while ( ob_get_level() > 0 ) {
46 public function finalSetup() {
47 global $wgDBadminuser, $wgDBadminpassword;
48 global $wgDBuser, $wgDBpassword, $wgDBservers, $wgLBFactoryConf;
50 # Prepare environment again, things might have changed in the settings files
51 $this->prepareEnvironment();
53 if ( isset( $wgDBadminuser ) ) {
54 $wgDBuser = $wgDBadminuser;
55 $wgDBpassword = $wgDBadminpassword;
59 * @var array $wgDBservers
61 foreach ( $wgDBservers as $i => $server ) {
62 $wgDBservers[$i]['user'] = $wgDBuser;
63 $wgDBservers[$i]['password'] = $wgDBpassword;
66 if ( isset( $wgLBFactoryConf['serverTemplate'] ) ) {
67 $wgLBFactoryConf['serverTemplate']['user'] = $wgDBuser;
68 $wgLBFactoryConf['serverTemplate']['password'] = $wgDBpassword;
70 $service = MediaWikiServices
::getInstance()->peekService( 'DBLoadBalancerFactory' );
76 require_once __DIR__
. '/../common/TestsAutoLoader.php';
78 TestSetup
::applyInitialConfig();
80 ExtensionRegistry
::getInstance()->setLoadTestClassesAndNamespaces( true );
83 public function execute() {
84 // Start an output buffer to avoid headers being sent by constructors,
85 // data providers, etc. (T206476)
88 fwrite( STDERR
, 'Using PHP ' . PHP_VERSION
. "\n" );
90 $command = new Command();
91 $args = $_SERVER['argv'];
92 $knownOpts = getopt( 'c:', [ 'configuration:', 'bootstrap:' ] ) ?
: [];
93 if ( !isset( $knownOpts['c'] ) && !isset( $knownOpts['configuration'] ) ) {
94 // XXX HAX: Use our default file. This is a temporary hack, to be removed when this file goes away
95 // or when T227900 is resolved.
96 $args[] = '--configuration=' . __DIR__
. '/suite.xml';
98 if ( !isset( $knownOpts['bootstrap'] ) ) {
99 $args[] = '--bootstrap=' . __DIR__
. '/bootstrap.maintenance.php';
101 $command->run( $args, true );
105 $deprecationMsg = <<<EOT
106 *******************************************************************************
107 DEPRECATED: The tests/phpunit/phpunit.php entry point has been deprecated. Use
108 `composer phpunit` instead.
109 *******************************************************************************
113 fwrite( STDERR
, $deprecationMsg );
115 if ( defined( 'MEDIAWIKI' ) ) {
116 exit( 'Wrong entry point?' );
119 if ( PHP_SAPI
!== 'cli' && PHP_SAPI
!== 'phpdbg' ) {
120 exit( 'This script must be run from the command line' );
123 define( 'MW_ENTRY_POINT', 'cli' );
125 if ( strval( getenv( 'MW_INSTALL_PATH' ) ) === '' ) {
126 putenv( 'MW_INSTALL_PATH=' . realpath( __DIR__
. '/../..' ) );
129 if ( getenv( 'PHPUNIT_WIKI' ) ) {
130 $wikiName = getenv( 'PHPUNIT_WIKI' );
131 $bits = explode( '-', $wikiName, 2 );
132 define( 'MW_DB', $bits[0] );
133 define( 'MW_PREFIX', $bits[1] ??
'' );
134 define( 'MW_WIKI_NAME', $wikiName );
137 // Define the MediaWiki entrypoint
138 define( 'MEDIAWIKI', true );
140 define( 'PHPUNIT_LEGACY_ENTRYPOINT', true );
142 $IP = getenv( 'MW_INSTALL_PATH' );
144 $wrapper = new PHPUnitMaintClass();
147 require_once "$IP/includes/BootstrapHelperFunctions.php";
149 $IP = wfDetectInstallPath(); // ensure MW_INSTALL_PATH is defined
150 wfDetectLocalSettingsFile( $IP );
152 function wfPHPUnitSetup() {
153 // phpcs:ignore MediaWiki.NamingConventions.ValidGlobalName.allowedPrefix
155 $wrapper->finalSetup();
158 define( 'MW_SETUP_CALLBACK', 'wfPHPUnitSetup' );
160 require_once "$IP/includes/Setup.php";
161 // Deregister handler from MWExceptionHandler::installHandle so that PHPUnit's own handler
162 // stays in tact. Needs to happen after including Setup.php, which calls MWExceptionHandler::installHandle().
163 restore_error_handler();
165 // Check that composer dependencies are up-to-date
166 if ( !getenv( 'MW_SKIP_EXTERNAL_DEPENDENCIES' ) ) {
167 $composerLockUpToDate = new CheckComposerLockUpToDate();
168 $composerLockUpToDate->loadParamsAndArgs( 'phpunit', [ 'quiet' => true ] );
169 $composerLockUpToDate->execute();