Fix installation failure due to unexpected dbpath under CLI installation
1. Make sure `wgSQLiteDataDir` is not empty.
2. Fix a logic bug
In the current logic, in web environment, SqliteInstaller::dataDirOKmaybeCreate()
will be executed twice, first in the DBConnect page [1] (with $create=true),
and the second time in Installer::performInstallation() [2] (with $create=false),
this is a sanity check.
But in cli environment, SqliteInstaller::dataDirOKmaybeCreate() will
be only executed once, called by Installer::performInstallation() (with $create=false).
So the Cli installer will abort because the data directory is checked
without the behavior of creating the directory.
In this case, I split dataDirOKmaybeCreate() into checkDataDir() and
createDataDir() according to its responsibility. And for web installation,
we just check the directory on DBConnect page instead of creating it and
then actually creating it in setupDatabase().
3. Add a unit test for SqliteInstaller::dataDirOKmaybeCreate
[1] DBConnect page call SqliteInstaller::submitConnectForm(),
::submitConnectForm() call ::dataDirOKmaybeCreate()
[2] Installer::performInstallation() call SqliteInstaller::setupDatabase(),
::setupDatabase() call ::dataDirOKmaybeCreate()
Bug: T217855
Change-Id: I139036b265716e9898fb76ba907c194f005ea318
2019-06-01 16:15:34 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @group sqlite
|
|
|
|
|
* @group medium
|
|
|
|
|
*/
|
2021-01-12 12:10:14 +00:00
|
|
|
class SqliteInstallerTest extends MediaWikiUnitTestCase {
|
Fix installation failure due to unexpected dbpath under CLI installation
1. Make sure `wgSQLiteDataDir` is not empty.
2. Fix a logic bug
In the current logic, in web environment, SqliteInstaller::dataDirOKmaybeCreate()
will be executed twice, first in the DBConnect page [1] (with $create=true),
and the second time in Installer::performInstallation() [2] (with $create=false),
this is a sanity check.
But in cli environment, SqliteInstaller::dataDirOKmaybeCreate() will
be only executed once, called by Installer::performInstallation() (with $create=false).
So the Cli installer will abort because the data directory is checked
without the behavior of creating the directory.
In this case, I split dataDirOKmaybeCreate() into checkDataDir() and
createDataDir() according to its responsibility. And for web installation,
we just check the directory on DBConnect page instead of creating it and
then actually creating it in setupDatabase().
3. Add a unit test for SqliteInstaller::dataDirOKmaybeCreate
[1] DBConnect page call SqliteInstaller::submitConnectForm(),
::submitConnectForm() call ::dataDirOKmaybeCreate()
[2] Installer::performInstallation() call SqliteInstaller::setupDatabase(),
::setupDatabase() call ::dataDirOKmaybeCreate()
Bug: T217855
Change-Id: I139036b265716e9898fb76ba907c194f005ea318
2019-06-01 16:15:34 +00:00
|
|
|
/**
|
|
|
|
|
* @covers SqliteInstaller::checkDataDir
|
|
|
|
|
*/
|
|
|
|
|
public function testCheckDataDir() {
|
|
|
|
|
$method = new ReflectionMethod( SqliteInstaller::class, 'checkDataDir' );
|
|
|
|
|
$method->setAccessible( true );
|
|
|
|
|
|
|
|
|
|
# Test 1: Should return fatal Status if $dir exist and it un-writable
|
|
|
|
|
if ( ( isset( $_SERVER['USER'] ) && $_SERVER['USER'] !== 'root' ) && !wfIsWindows() ) {
|
|
|
|
|
// We can't simulate this environment under Windows or login as root
|
|
|
|
|
$dir = sys_get_temp_dir() . '/' . uniqid( 'MediaWikiTest' );
|
|
|
|
|
mkdir( $dir, 0000 );
|
|
|
|
|
/** @var Status $status */
|
|
|
|
|
$status = $method->invoke( null, $dir );
|
|
|
|
|
$this->assertFalse( $status->isGood() );
|
|
|
|
|
$this->assertSame( 'config-sqlite-dir-unwritable', $status->getErrors()[0]['message'] );
|
|
|
|
|
rmdir( $dir );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Test 2: Should return fatal Status if $dir not exist and it parent also not exist
|
|
|
|
|
$dir = sys_get_temp_dir() . '/' . uniqid( 'MediaWikiTest' ) . '/' . uniqid( 'MediaWikiTest' );
|
|
|
|
|
$status = $method->invoke( null, $dir );
|
|
|
|
|
$this->assertFalse( $status->isGood() );
|
|
|
|
|
|
|
|
|
|
# Test 3: Should return good Status if $dir not exist and it parent writable
|
|
|
|
|
$dir = sys_get_temp_dir() . '/' . uniqid( 'MediaWikiTest' );
|
|
|
|
|
/** @var Status $status */
|
|
|
|
|
$status = $method->invoke( null, $dir );
|
|
|
|
|
$this->assertTrue( $status->isGood() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers SqliteInstaller::createDataDir
|
|
|
|
|
*/
|
|
|
|
|
public function testCreateDataDir() {
|
|
|
|
|
$method = new ReflectionMethod( SqliteInstaller::class, 'createDataDir' );
|
|
|
|
|
$method->setAccessible( true );
|
|
|
|
|
|
|
|
|
|
# Test 1: Should return fatal Status if $dir not exist and it parent un-writable
|
|
|
|
|
if ( ( isset( $_SERVER['USER'] ) && $_SERVER['USER'] !== 'root' ) && !wfIsWindows() ) {
|
|
|
|
|
// We can't simulate this environment under Windows or login as root
|
|
|
|
|
$random = uniqid( 'MediaWikiTest' );
|
|
|
|
|
$dir = sys_get_temp_dir() . '/' . $random . '/' . uniqid( 'MediaWikiTest' );
|
|
|
|
|
mkdir( sys_get_temp_dir() . "/$random", 0000 );
|
|
|
|
|
/** @var Status $status */
|
|
|
|
|
$status = $method->invoke( null, $dir );
|
|
|
|
|
$this->assertFalse( $status->isGood() );
|
|
|
|
|
$this->assertSame( 'config-sqlite-mkdir-error', $status->getErrors()[0]['message'] );
|
|
|
|
|
rmdir( sys_get_temp_dir() . "/$random" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Test 2: Test .htaccess content after created successfully
|
|
|
|
|
$dir = sys_get_temp_dir() . '/' . uniqid( 'MediaWikiTest' );
|
|
|
|
|
$status = $method->invoke( null, $dir );
|
|
|
|
|
$this->assertTrue( $status->isGood() );
|
|
|
|
|
$this->assertSame( "Deny from all\n", file_get_contents( "$dir/.htaccess" ) );
|
|
|
|
|
unlink( "$dir/.htaccess" );
|
|
|
|
|
rmdir( $dir );
|
|
|
|
|
}
|
|
|
|
|
}
|