class TestSiteInstallCommand
Same name in other branches
- 9 core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php \Drupal\TestSite\Commands\TestSiteInstallCommand
- 8.9.x core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php \Drupal\TestSite\Commands\TestSiteInstallCommand
- 11.x core/tests/Drupal/TestSite/Commands/TestSiteInstallCommand.php \Drupal\TestSite\Commands\TestSiteInstallCommand
Command to create a test Drupal site.
@internal
Hierarchy
- class \Drupal\TestSite\Commands\TestSiteInstallCommand extends \Symfony\Component\Console\Command\Command uses \Drupal\Core\Test\FunctionalTestSetupTrait, \Drupal\Tests\RandomGeneratorTrait, \Drupal\Core\Test\TestSetupTrait
Expanded class hierarchy of TestSiteInstallCommand
1 file declares its use of TestSiteInstallCommand
- TestSiteApplication.php in core/
tests/ Drupal/ TestSite/ TestSiteApplication.php
File
-
core/
tests/ Drupal/ TestSite/ Commands/ TestSiteInstallCommand.php, line 27
Namespace
Drupal\TestSite\CommandsView source
class TestSiteInstallCommand extends Command {
use FunctionalTestSetupTrait {
installParameters as protected installParametersTrait;
}
use RandomGeneratorTrait;
use TestSetupTrait {
changeDatabasePrefix as protected changeDatabasePrefixTrait;
}
/**
* The theme to install as the default for testing.
*
* Defaults to the install profile's default theme, if it specifies any.
*/
protected string $defaultTheme;
/**
* The base URL.
*/
protected string $baseUrl;
/**
* The original array of shutdown function callbacks.
*/
protected array $originalShutdownCallbacks = [];
/**
* The translation file directory for the test environment.
*
* This is set in BrowserTestBase::prepareEnvironment().
*/
protected string $translationFilesDirectory;
/**
* The config importer that can be used in a test.
*/
protected ?ConfigImporter $configImporter;
/**
* The install profile to use.
*
* @var string
*/
protected $profile = 'testing';
/**
* Time limit in seconds for the test.
*
* Used by \Drupal\Core\Test\FunctionalTestSetupTrait::prepareEnvironment().
*
* @var int
*/
protected $timeLimit = 500;
/**
* The language to install the site in.
*
* @var string
*/
protected $langcode = 'en';
/**
* {@inheritdoc}
*
* @todo Remove and fix test to not rely on super user.
* @see https://www.drupal.org/project/drupal/issues/3437620
*/
public function __construct(?string $name = NULL) {
parent::__construct($name);
$this->usesSuperUserAccessPolicy = TRUE;
}
/**
* {@inheritdoc}
*/
protected function configure() {
$this->setName('install')
->setDescription('Creates a test Drupal site')
->setHelp('The details to connect to the test site created will be displayed upon success. It will contain the database prefix and the user agent.')
->addOption('setup-file', NULL, InputOption::VALUE_OPTIONAL, 'The path to a PHP file containing a class to setup configuration used by the test, for example, core/tests/Drupal/TestSite/TestSiteMultilingualInstallTestScript.php.')
->addOption('db-url', NULL, InputOption::VALUE_OPTIONAL, 'URL for database. Defaults to the environment variable SIMPLETEST_DB.', getenv('SIMPLETEST_DB'))
->addOption('base-url', NULL, InputOption::VALUE_OPTIONAL, 'Base URL for site under test. Defaults to the environment variable SIMPLETEST_BASE_URL.', getenv('SIMPLETEST_BASE_URL'))
->addOption('install-profile', NULL, InputOption::VALUE_OPTIONAL, 'Install profile to install the site in. Defaults to testing.', 'testing')
->addOption('langcode', NULL, InputOption::VALUE_OPTIONAL, 'The language to install the site in. Defaults to en.', 'en')
->addOption('json', NULL, InputOption::VALUE_NONE, 'Output test site connection details in JSON.')
->addUsage('--setup-file core/tests/Drupal/TestSite/TestSiteMultilingualInstallTestScript.php --json')
->addUsage('--install-profile demo_umami --langcode fr')
->addUsage('--base-url "http://example.com" --db-url "mysql://username:password@localhost/database_name#table_prefix"');
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output) : int {
// Determines and validates the setup class prior to installing a database
// to avoid creating unnecessary sites.
$root = dirname(__DIR__, 5);
chdir($root);
$class_name = $this->getSetupClass($input->getOption('setup-file'));
// Ensure we can install a site in the sites/simpletest directory.
$this->ensureDirectory($root);
$db_url = $input->getOption('db-url');
$base_url = $input->getOption('base-url');
putenv("SIMPLETEST_DB={$db_url}");
putenv("SIMPLETEST_BASE_URL={$base_url}");
// Manage site fixture.
$this->setup($input->getOption('install-profile'), $class_name, $input->getOption('langcode'));
// Make sure there is an entry in sites.php for the new site.
$fs = new Filesystem();
if (!$fs->exists($root . '/sites/sites.php')) {
$fs->copy($root . '/sites/example.sites.php', $root . '/sites/sites.php');
}
$parsed = parse_url($base_url);
$port = $parsed['port'] ?? 80;
$host = $parsed['host'] ?? 'localhost';
// Remove 'sites/' from the beginning of the path.
$site_path = substr($this->siteDirectory, 6);
$fs->appendToFile($root . '/sites/sites.php', "\$sites['{$port}.{$host}'] = '{$site_path}';");
$user_agent = drupal_generate_test_ua($this->databasePrefix);
if ($input->getOption('json')) {
$output->writeln(json_encode([
'db_prefix' => $this->databasePrefix,
'user_agent' => $user_agent,
'site_path' => $this->siteDirectory,
]));
}
else {
$output->writeln('<info>Successfully installed a test site</info>');
$io = new SymfonyStyle($input, $output);
$io->table([], [
[
'Database prefix',
$this->databasePrefix,
],
[
'User agent',
$user_agent,
],
[
'Site path',
$this->siteDirectory,
],
]);
}
return 0;
}
/**
* Gets the setup class.
*
* @param string|null $file
* The file to get the setup class from.
*
* @return string|null
* The setup class contained in the provided $file.
*
* @throws \InvalidArgumentException
* Thrown if the file does not exist, does not contain a class or the class
* does not implement \Drupal\TestSite\TestSetupInterface or
* \Drupal\TestSite\TestPreinstallInterface.
*/
protected function getSetupClass($file) {
if ($file === NULL) {
return;
}
if (!file_exists($file)) {
throw new \InvalidArgumentException("The file {$file} does not exist.");
}
$classes = get_declared_classes();
include_once $file;
$new_classes = array_values(array_diff(get_declared_classes(), $classes));
if (empty($new_classes)) {
throw new \InvalidArgumentException("The file {$file} does not contain a class.");
}
$class = array_pop($new_classes);
if (!is_subclass_of($class, TestSetupInterface::class) && !is_subclass_of($class, TestPreinstallInterface::class)) {
throw new \InvalidArgumentException("The class {$class} contained in {$file} needs to implement \\Drupal\\TestSite\\TestSetupInterface or \\Drupal\\TestSite\\TestPreinstallInterface");
}
return $class;
}
/**
* Ensures that the sites/simpletest directory exists and is writable.
*
* @param string $root
* The Drupal root.
*/
protected function ensureDirectory($root) {
if (!is_writable($root . '/sites/simpletest')) {
if (!@mkdir($root . '/sites/simpletest')) {
throw new \RuntimeException($root . '/sites/simpletest must exist and be writable to install a test site');
}
}
}
/**
* Creates a test drupal installation.
*
* @param string $profile
* (optional) The installation profile to use.
* @param string $setup_class
* (optional) Setup class. A PHP class to setup configuration used by the
* test.
* @param string $langcode
* (optional) The language to install the site in.
*/
public function setup($profile = 'testing', $setup_class = NULL, $langcode = 'en') {
$this->profile = $profile;
$this->langcode = $langcode;
$this->setupBaseUrl();
$this->prepareEnvironment();
$this->executePreinstallClass($setup_class);
$this->installDrupal();
$this->executeSetupClass($setup_class);
}
/**
* Installs Drupal into the test site.
*/
protected function installDrupal() {
$this->initUserSession();
$this->prepareSettings();
$this->doInstall();
$this->initSettings();
$container = $this->initKernel(\Drupal::request());
$this->initConfig($container);
}
/**
* Uses the setup file to configure Drupal.
*
* @param string $class
* The fully qualified class name, which should set up Drupal for tests. For
* example this class could create content types and fields or install
* modules. The class needs to implement TestSetupInterface.
*
* @see \Drupal\TestSite\TestSetupInterface
*/
protected function executeSetupClass($class) {
if (is_subclass_of($class, TestSetupInterface::class)) {
/** @var \Drupal\TestSite\TestSetupInterface $instance */
$instance = new $class();
$instance->setup();
}
}
/**
* Uses the setup file to configure the environment prior to install.
*
* @param string $class
* The fully qualified class name, which should set up the environment prior
* to installing Drupal for tests. For example this class could create
* translations that are used during the installer.
*
* @see \Drupal\TestSite\TestPreinstallInterface
*/
protected function executePreinstallClass($class) {
if (is_subclass_of($class, TestPreinstallInterface::class)) {
/** @var \Drupal\TestSite\TestPreinstallInterface $instance */
$instance = new $class();
$instance->preinstall($this->databasePrefix, $this->siteDirectory);
}
}
/**
* {@inheritdoc}
*/
protected function installParameters() {
$parameters = $this->installParametersTrait();
$parameters['parameters']['langcode'] = $this->langcode;
return $parameters;
}
/**
* {@inheritdoc}
*/
protected function changeDatabasePrefix() {
// Ensure that we use the database from SIMPLETEST_DB environment variable.
Database::removeConnection('default');
$this->changeDatabasePrefixTrait();
}
/**
* {@inheritdoc}
*/
protected function prepareDatabasePrefix() {
// Override this method so that we can force a lock to be created.
$test_db = new TestDatabase(NULL, TRUE);
$this->siteDirectory = $test_db->getTestSitePath();
$this->databasePrefix = $test_db->getDatabasePrefix();
}
}
Members
Title Sort descending | Deprecated | Modifiers | Object type | Summary | Member alias | Overriden Title | Overrides |
---|---|---|---|---|---|---|---|
FunctionalTestSetupTrait::$apcuEnsureUniquePrefix | protected | property | The flag to set 'apcu_ensure_unique_prefix' setting. | 1 | |||
FunctionalTestSetupTrait::$classLoader | protected | property | The class loader to use for installation and initialization of setup. | ||||
FunctionalTestSetupTrait::$rootUser | protected | property | The "#1" admin user. | ||||
FunctionalTestSetupTrait::$usesSuperUserAccessPolicy | protected | property | Set to TRUE to make user 1 a super user. | 10 | |||
FunctionalTestSetupTrait::doInstall | protected | function | Execute the non-interactive installer. | 2 | |||
FunctionalTestSetupTrait::getDatabaseTypes | protected | function | Returns all supported database driver installer objects. | ||||
FunctionalTestSetupTrait::initConfig | protected | function | Initialize various configurations post-installation. | 1 | |||
FunctionalTestSetupTrait::initKernel | protected | function | Initializes the kernel after installation. | ||||
FunctionalTestSetupTrait::initSettings | protected | function | Initialize settings created during install. | ||||
FunctionalTestSetupTrait::initUserSession | protected | function | Initializes user 1 for the site to be installed. | ||||
FunctionalTestSetupTrait::installDefaultThemeFromClassProperty | protected | function | Installs the default theme defined by `static::$defaultTheme` when needed. | 1 | |||
FunctionalTestSetupTrait::installModulesFromClassProperty | protected | function | Install modules defined by `static::$modules`. | 1 | |||
FunctionalTestSetupTrait::installParameters | protected | function | Returns the parameters that will be used when the test installs Drupal. | Aliased as: installParametersTrait | 8 | ||
FunctionalTestSetupTrait::prepareEnvironment | protected | function | Prepares the current environment for running the test. | 28 | |||
FunctionalTestSetupTrait::prepareRequestForGenerator | protected | function | Creates a mock request and sets it on the generator. | ||||
FunctionalTestSetupTrait::prepareSettings | protected | function | Prepares site settings and services before installation. | 4 | |||
FunctionalTestSetupTrait::rebuildAll | protected | function | Resets and rebuilds the environment after setup. | ||||
FunctionalTestSetupTrait::rebuildContainer | protected | function | Rebuilds \Drupal::getContainer(). | ||||
FunctionalTestSetupTrait::resetAll | protected | function | Resets all data structures after having enabled new modules. | ||||
FunctionalTestSetupTrait::setContainerParameter | protected | function | Changes parameters in the services.yml file. | ||||
FunctionalTestSetupTrait::setupBaseUrl | protected | function | Sets up the base URL based upon the environment variable. | ||||
FunctionalTestSetupTrait::writeSettings | protected | function | Rewrites the settings.php file of the test site. | 1 | |||
RandomGeneratorTrait::getRandomGenerator | protected | function | Gets the random generator for the utility methods. | ||||
RandomGeneratorTrait::randomMachineName | protected | function | Generates a unique random string containing letters and numbers. | ||||
RandomGeneratorTrait::randomObject | public | function | Generates a random PHP object. | ||||
RandomGeneratorTrait::randomString | public | function | Generates a pseudo-random string of ASCII characters of codes 32 to 126. | ||||
RandomGeneratorTrait::randomStringValidate | Deprecated | public | function | Callback for random string validation. | |||
RefreshVariablesTrait::refreshVariables | protected | function | Refreshes in-memory configuration and state information. | 2 | |||
SessionTestTrait::$sessionName | protected | property | The name of the session cookie. | ||||
SessionTestTrait::generateSessionName | protected | function | Generates a session cookie name. | ||||
SessionTestTrait::getSessionName | protected | function | Returns the session name in use on the child site. | ||||
TestSetupTrait::$configSchemaCheckerExclusions | protected static | property | An array of config object names that are excluded from schema checking. | 2 | |||
TestSetupTrait::$container | protected | property | The dependency injection container used in the test. | ||||
TestSetupTrait::$databasePrefix | protected | property | The database prefix of this test run. | ||||
TestSetupTrait::$kernel | protected | property | The DrupalKernel instance used in the test. | ||||
TestSetupTrait::$originalSite | protected | property | The site directory of the original parent site. | ||||
TestSetupTrait::$privateFilesDirectory | protected | property | The private file directory for the test environment. | ||||
TestSetupTrait::$publicFilesDirectory | protected | property | The public file directory for the test environment. | ||||
TestSetupTrait::$root | protected | property | The app root. | ||||
TestSetupTrait::$siteDirectory | protected | property | The site directory of this test run. | ||||
TestSetupTrait::$strictConfigSchema | protected | property | Set to TRUE to strict check all configuration saved. | 4 | |||
TestSetupTrait::$tempFilesDirectory | protected | property | The temporary file directory for the test environment. | ||||
TestSetupTrait::$testId | protected | property | The test run ID. | ||||
TestSetupTrait::changeDatabasePrefix | protected | function | Changes the database connection to the prefixed one. | Aliased as: changeDatabasePrefixTrait | |||
TestSetupTrait::getConfigSchemaExclusions | protected | function | Gets the config schema exclusions for this test. | ||||
TestSetupTrait::getDatabaseConnection | Deprecated | public static | function | Returns the database connection to the site under test. | |||
TestSiteInstallCommand::$baseUrl | protected | property | The base URL. | ||||
TestSiteInstallCommand::$configImporter | protected | property | The config importer that can be used in a test. | ||||
TestSiteInstallCommand::$defaultTheme | protected | property | The theme to install as the default for testing. | ||||
TestSiteInstallCommand::$langcode | protected | property | The language to install the site in. | ||||
TestSiteInstallCommand::$originalShutdownCallbacks | protected | property | The original array of shutdown function callbacks. | ||||
TestSiteInstallCommand::$profile | protected | property | The install profile to use. | ||||
TestSiteInstallCommand::$timeLimit | protected | property | Time limit in seconds for the test. | ||||
TestSiteInstallCommand::$translationFilesDirectory | protected | property | The translation file directory for the test environment. | ||||
TestSiteInstallCommand::changeDatabasePrefix | protected | function | |||||
TestSiteInstallCommand::configure | protected | function | |||||
TestSiteInstallCommand::ensureDirectory | protected | function | Ensures that the sites/simpletest directory exists and is writable. | ||||
TestSiteInstallCommand::execute | protected | function | |||||
TestSiteInstallCommand::executePreinstallClass | protected | function | Uses the setup file to configure the environment prior to install. | ||||
TestSiteInstallCommand::executeSetupClass | protected | function | Uses the setup file to configure Drupal. | ||||
TestSiteInstallCommand::getSetupClass | protected | function | Gets the setup class. | ||||
TestSiteInstallCommand::installDrupal | protected | function | Installs Drupal into the test site. | ||||
TestSiteInstallCommand::installParameters | protected | function | |||||
TestSiteInstallCommand::prepareDatabasePrefix | protected | function | Generates a database prefix for running tests. | Overrides TestSetupTrait::prepareDatabasePrefix | |||
TestSiteInstallCommand::setup | public | function | Creates a test drupal installation. | ||||
TestSiteInstallCommand::__construct | public | function | @todo Remove and fix test to not rely on super user. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.