Skip to content

Commit

Permalink
Issue #3135629 by alexpott, dww, daffie, jungle, Rkumar, balsama, xjm…
Browse files Browse the repository at this point in the history
…, catch: Minimum MySQL version requirement is not confirmed when upgrading existing sites from Drupal 8 to Drupal 9
  • Loading branch information
xjm committed May 15, 2020
1 parent cc83c19 commit a9ff5d0
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 1 deletion.
13 changes: 13 additions & 0 deletions lib/Drupal/Core/Database/Install/Tasks.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,19 @@ public function runTasks() {
return $this->results['fail'];
}

/**
* Checks engine version requirements for the status report.
*
* This method is called during runtime and update requirements checks.
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup[]
* A list of error messages.
*/
final public function engineVersionRequirementsCheck() {
$this->checkEngineVersion();
return $this->results['fail'];
}

/**
* Check if we can connect to the database.
*/
Expand Down
17 changes: 16 additions & 1 deletion modules/system/system.install
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,11 @@ function system_requirements($phase) {
$requirements['database_extensions']['value'] = t('Enabled');
}
}
else {

if ($phase === 'runtime' || $phase === 'update') {
// Database information.
$class = Database::getConnection()->getDriverClass('Install\\Tasks');
/** @var \Drupal\Core\Database\Install\Tasks $tasks */
$tasks = new $class();
$requirements['database_system'] = [
'title' => t('Database system'),
Expand All @@ -447,6 +449,19 @@ function system_requirements($phase) {
'title' => t('Database system version'),
'value' => Database::getConnection()->version(),
];

$errors = $tasks->engineVersionRequirementsCheck();
$error_count = count($errors);
if ($error_count > 0) {
$error_message = [
'#theme' => 'item_list',
'#items' => $errors,
// Use the comma-list style to display a single error without bullets.
'#context' => ['list_style' => $error_count === 1 ? 'comma-list' : ''],
];
$requirements['database_system_version']['severity'] = REQUIREMENT_ERROR;
$requirements['database_system_version']['description'] = $error_message;
}
}

// Test PHP memory_limit
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace Drupal\driver_test\Driver\Database\DrivertestMysqlDeprecatedVersion;

use Drupal\Core\Database\Driver\mysql\Connection as CoreConnection;

/**
* MySQL test implementation of \Drupal\Core\Database\Connection.
*/
class Connection extends CoreConnection {

/**
* Constructs a Connection object.
*/
public function __construct(\PDO $connection, array $connection_options = []) {
// Alias the MySQL classes to avoid having unnecessary copies.
foreach (['Delete', 'Insert', 'Merge', 'Schema', 'Upsert', 'Select', 'Update'] as $class) {
class_alias('Drupal\\Core\\Database\\Driver\\mysql\\' . $class, 'Drupal\\driver_test\\Driver\\Database\\DrivertestMysqlDeprecatedVersion\\' . $class);
}
parent::__construct($connection, $connection_options);
}

/**
* Hardcoded database server version.
*
* Faking that we are on a deprecated database.
*
* @var string
*/
protected $databaseVersion = '5.5.2';

/**
* {@inheritdoc}
*/
public function driver() {
return 'DrivertestMysqlDeprecatedVersion';
}

/**
* {@inheritdoc}
*/
public function version() {
return $this->databaseVersion;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Drupal\driver_test\Driver\Database\DrivertestMysqlDeprecatedVersion\Install;

use Drupal\Core\Database\Driver\mysql\Install\Tasks as CoreTasks;

/**
* Specifies installation tasks for MySQL test databases.
*/
class Tasks extends CoreTasks {

/**
* {@inheritdoc}
*/
public function name() {
return t('MySQL deprecated version by the driver_test module');
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Drupal\Tests\system\Functional\Update;

use Drupal\Core\Database\Database;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\UpdatePathTestTrait;

/**
* Tests that updates fail if the database does not meet the minimum version.
*
* @group Update
*/
class DatabaseVersionCheckUpdateTest extends BrowserTestBase {
use UpdatePathTestTrait;

/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';

/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->ensureUpdatesToRun();
}

/**
* Tests that updates fail if the database does not meet the minimum version.
*/
public function testUpdate() {
if (Database::getConnection()->driver() !== 'mysql') {
$this->markTestSkipped('This test only works with the mysql driver');
}

// Use a database driver that reports a fake database version that does
// not meet requirements. Only change the necessary settings in the database
// settings array so that run-tests.sh continues to work.
$autoload = Database::findDriverAutoloadDirectory('Drupal\driver_test\Driver\Database\DrivertestMysqlDeprecatedVersion', \Drupal::root());
$settings['databases']['default']['default']['driver'] = (object) [
'value' => 'DrivertestMysqlDeprecatedVersion',
'required' => TRUE,
];
$settings['databases']['default']['default']['namespace'] = (object) [
'value' => 'Drupal\\driver_test\\Driver\\Database\\DrivertestMysqlDeprecatedVersion',
'required' => TRUE,
];
$settings['databases']['default']['default']['autoload'] = (object) [
'value' => $autoload,
'required' => TRUE,
];
$settings['settings'] = [
'update_free_access' => (object) [
'value' => TRUE,
'required' => TRUE,
],
];
$this->writeSettings($settings);

$this->drupalGet(Url::fromRoute('system.db_update'));
$this->assertSession()->pageTextContains('Errors found');
$this->assertSession()->pageTextContains('The database server version 5.5.2 is less than the minimum required version');
}

}

0 comments on commit a9ff5d0

Please sign in to comment.