From 2838e4ebaf731234eecb0391e919116837820224 Mon Sep 17 00:00:00 2001 From: Philipp Date: Mon, 27 Aug 2018 06:15:55 +0200 Subject: [PATCH] Automatic Install Tests & Doku (#5674) * Automatic Installation Testing - New dev-library "mikey179/vfsStream" - created "reload" method for App-Reloads - ConsoleTest now using virtual directory - Adding Automatic Installation Tests - Fixing some probable install-failures * Updating README for Automatic Installation * Updating README for Automatic Installation * Bugfix normal installation * Fixing copying of config files --- composer.json | 3 +- composer.lock | 48 ++- doc/Install.md | 82 ++++- doc/de/Install.md | 83 ++++- mod/install.php | 2 - src/App.php | 76 ++-- src/Core/Console/AutomaticInstallation.php | 46 +-- src/Core/Install.php | 7 +- .../AutomaticInstallationConsoleTest.php | 333 ++++++++++++++++++ tests/src/Core/Console/ConfigConsoleTest.php | 15 +- tests/src/Core/Console/ConsoleTest.php | 61 +++- 11 files changed, 655 insertions(+), 101 deletions(-) create mode 100644 tests/src/Core/Console/AutomaticInstallationConsoleTest.php diff --git a/composer.json b/composer.json index 9ef0dcd101..04e4b655da 100644 --- a/composer.json +++ b/composer.json @@ -74,7 +74,8 @@ "require-dev": { "phpunit/dbunit": "^2.0", "phpdocumentor/reflection-docblock": "^3.0.2", - "phpunit/php-token-stream": "^1.4.2" + "phpunit/php-token-stream": "^1.4.2", + "mikey179/vfsStream": "^1.6" }, "scripts": { "test": "phpunit" diff --git a/composer.lock b/composer.lock index 409deb2e8f..76c20a1b93 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "9e24971ae9340c5d9d4d4ca477d4ec29", + "content-hash": "d62c3e3d6971ee63a862a22ff3cd3768", "packages": [ { "name": "asika/simple-console", @@ -2252,6 +2252,52 @@ ], "time": "2015-06-14T21:17:01+00:00" }, + { + "name": "mikey179/vfsStream", + "version": "v1.6.5", + "source": { + "type": "git", + "url": "https://github.com/mikey179/vfsStream.git", + "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mikey179/vfsStream/zipball/d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", + "reference": "d5fec95f541d4d71c4823bb5e30cf9b9e5b96145", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/", + "time": "2017-08-01T08:02:14+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.7.0", diff --git a/doc/Install.md b/doc/Install.md index 300a9c82d3..3854c32bce 100644 --- a/doc/Install.md +++ b/doc/Install.md @@ -111,29 +111,85 @@ You might wish to move/rename `config/local.ini.php` to another name and empty ( ### Option B: Run the automatic install script -Open the file htconfig.php in the main Friendica directory with a text editor. -Remove the `die('...');` line and edit the lines to suit your installation (MySQL, language, theme etc.). -Then save the file (do not rename it). +You have the following options to automatically install Friendica: +- creating a prepared config file (f.e. `prepared.ini.php`) +- using environment variables (f.e. `MYSQL_HOST`) +- using options (f.e. `--dbhost `) -Navigate to the main Friendica directory and execute the following command: +You can combine environment variables and options, but be aware that options are prioritized over environment variables. + +For more information during the installation, you can use this command line option - bin/console autoinstall + bin/console autoinstall -v -Or if you wish to include all optional checks, execute this statement instead: +If you wish to include all optional checks, use `-a` like this statement: bin/console autoinstall -a + +*If* the automatic installation fails for any reason, check the following: -At this point visit your website again, and register your personal account. +* Does `config/local.ini.php` already exist? If yes, the automatic installation won't start +* Are the options in the `config/local.ini.php` correct? If not, edit them directly. +* Is the empty MySQL-database created? If not, create it. -*If* the automatic installation fails for any reason, check the following: +#### B.1: Config file -* Does "config/local.ini.php" already exist? If yes, the automatic installation won't start -* Are the settings inside "htconfig.php" correct? If not, edit the file again. -* Is the empty MySQL-database created? If not, create it. +You can use a prepared config file like [local-sample.ini.php](config/local-sample.ini.php). -For more information during the installation, you can use this command line option +Navigate to the main Friendica directory and execute the following command: - bin/console autoinstall -v + bin/console autoinstall -f + +#### B.2: Environment variables + +There are two types of environment variables. +- those you can use in normal mode too (Currently just **database credentials**) +- those you can only use during installation (because Friendica will normally ignore it) + +You can use the options during installation too and skip some of the environment variables. + +**Database credentials** + +if you don't use the option `--savedb` during installation, the DB credentials will **not** be saved in the `config/local.ini.php`. + +- `MYSQL_HOST` The host of the mysql/mariadb database +- `MYSQL_PORT` The port of the mysql/mariadb database +- `MYSQL_USERNAME` The username of the mysql database login (used for mysql) +- `MYSQL_USER` The username of the mysql database login (used for mariadb) +- `MYSQL_PASSWORD` The password of the mysql/mariadb database login +- `MYSQL_DATABASE` The name of the mysql/mariadb database + +**Friendica settings** + +This variables wont be used at normal Friendica runtime. +Instead, they get saved into `config/local.ini.php`. + +- `FRIENDICA_PHP_PATH` The path of the PHP binary +- `FRIENDICA_ADMIN_MAIL` The admin email address of Friendica (this email will be used for admin access) +- `FRIENDICA_TZ` The timezone of Friendica +- `FRIENDICA_LANG` The langauge of Friendica + +Navigate to the main Friendica directory and execute the following command: + + bin/console autoinstall [--savedb] + +#### B.3: Execution options + +All options will be saved in the `config/local.ini.php` and are overruling the associated environment variables. + +- `-H|--dbhost ` The host of the mysql/mariadb database (env `MYSQL_HOST`) +- `-p|--dbport ` The port of the mysql/mariadb database (env `MYSQL_PORT`) +- `-U|--dbuser ` The username of the mysql/mariadb database login (env `MYSQL_USER` or `MYSQL_USERNAME`) +- `-P|--dbpass ` The password of the mysql/mariadb database login (env `MYSQL_PASSWORD`) +- `-d|--dbdata ` The name of the mysql/mariadb database (env `MYSQL_DATABASE`) +- `-b|--phppath ` The path of the PHP binary (env `FRIENDICA_PHP_PATH`) +- `-A|--admin ` The admin email address of Friendica (env `FRIENDICA_ADMIN_MAIL`) +- `-T|--tz ` The timezone of Friendica (env `FRIENDICA_TZ`) +- `-L|--land ` The language of Friendica (env `FRIENDICA_LANG`) + +Navigate to the main Friendica directory and execute the following command: + + bin/console autoinstall [options] ### Prepare .htaccess file diff --git a/doc/de/Install.md b/doc/de/Install.md index 84941d9282..05a4e1e465 100644 --- a/doc/de/Install.md +++ b/doc/de/Install.md @@ -112,28 +112,87 @@ Alle Registrierungsprobleme sollten automatisch behebbar sein. Wenn du irgendwelche **kritischen** Fehler zu diesen Zeitpunkt erhalten solltest, deutet das darauf hin, dass die Datenbank nicht korrekt installiert wurde. Du kannst bei Bedarf die Datei config/local.ini.php verschieben/umbenennen und die Datenbank leeren (als „Dropping“ bezeichnet), so dass du mit einem sauberen System neu starten kannst. -### Option B: Starte das manuelle Installationsscript +### Option B: Starte das automatische Installationsscript -Öffne die Datei htconfig.php im Friendica-Hauptordner mit einem Text-Editor. -Entferne die `die('...');` Zeile und bearbeite die Einstellungen so, das sie zu deinem System passen (MySQL, Sprache, Theme etc.). -Dann speichere die Datei (jedoch nicht umbenennen). +Es existieren folgende Varianten zur automatischen Installation von Friendica: +- Eine vorgefertigte Konfigurationsdatei erstellen (z.B. `prepared.ini.php`) +- Verwendung von Umgebungsvariablen (z.B. `MYSQL_HOST`) +- Verwendung von Optionen (z.B. `--dbhost `) -Gehe in den Friendica-Hauptordner und führe den Kommandozeilen Befehl aus: +Umgebungsvariablen und Optionen können auch kombiniert werden. +Dabei ist jedoch darauf zu achten, dass etwaige Optionen immer die zugehörigen Umgebungsvariablen überschreiben. + +Für mehr Informationen kannst du diese Option verwenden: - bin/console autoinstall + bin/console autoinstall -v -Oder falls du alle optionalen Checks ausfürehn lassen möchtest, benutze diese Option: +Falls du alle optionalen Checks ausfürehn lassen möchtest, benutze diese Option: bin/console autoinstall -a *Wenn* die automatisierte Installation aus irgendeinem Grund fehlschlägt, dann prüfe das Folgende: -* Existiert die `config/local.ini.php`? Falls ja, wird die automatisierte Installation nicht gestartet. -* Sind Einstellungen in der `config/local.ini.php` korrekt? Falls nicht, bitte bearbeite diese Datei erneut. -* Ist die leere MySQL-Datenbank erstellt? Falls nicht, erstelle diese. +* Existiert die `config/local.ini.php`? Falls ja, wird die automatisierte Installation nicht gestartet. +* Sind Einstellungen in der `config/local.ini.php` korrekt? Falls nicht, bitte bearbeite diese Datei erneut. +* Ist die leere MySQL-Datenbank erstellt? Falls nicht, erstelle diese. -Für mehr Informationen kannst du diese Option verwenden: +#### B.1: Konfigurationsdatei - bin/console autoinstall -v +Für diese Variante muss ein Konfigurationsdatei bereits vor der Installation fertig definiert sein (z.B. [local-sample.ini.php](config/local-sample.ini.php). + +Gehe im Anschluss in den Friendica-Hauptordner und führe den Kommandozeilen Befehl aus: + + bin/console autoinstall -f + +#### B.2: Umgebungsvariablen + +Es existieren Zwei Arten von Umgebungsvariablen in Friendica: +- Jene, die auch im normalen Betrieb verwendet werden können (derzeit ausschließlich **Datenbank Einstellungen**) +- Jene, die nur während der Installation verwedent werden können (im normalen Betrieb werden sie ignoriert) + +Umgebungsvariablen können auch durch adäquate Optionen (z.B. `--dbhost `)übersteuert werden. + +**Datenbank Einstellungen** + +Nur wenn die Option `--savedb` gesetzt ist, werden diese Umgebungsvariablen auch in `config/local.ini.php` gespeichert! + +- `MYSQL_HOST` Der Host der MySQL/MariaDB Datenbank +- `MYSQL_PORT` Der Port der MySQL/MariaDB Datenbank +- `MYSQL_USERNAME` Der Benutzername des MySQL Datenbanklogins (MySql - Variante) +- `MYSQL_USER` Der Benutzername des MariaDB Datenbanklogins (MariaDB-Variante) +- `MYSQL_PASSWORD` Das Passwort der MySQL/MariaDB Datenbanklogins +- `MYSQL_DATABASE` Der Name der MySQL/MariaDB Datenbank + +**Friendica Einstellungen** + +Diese Umgebungsvariablen können nicht während des normalen Friendica Betriebs verwendet werden. +Sie werden stattdessen direkt in `config/local.ini.php` gespeichert. + +- `FRIENDICA_PHP_PATH` Der Pfad zur PHP-Datei +- `FRIENDICA_ADMIN_MAIL` Die Admin E-Mail Adresse dieses Friendica Knotens (wird auch für den Admin-Zugang benötigt) +- `FRIENDICA_TZ` Die Zeitzone von Friendica +- `FRIENDICA_LANG` Die Sprache von Friendica + +Gehe im Anschluss in den Friendica-Hauptordner und führe den Kommandozeilen Befehl aus: + + bin/console autoinstall [--savedb] + +#### B.3: Optionen + +Alle Optionen werden in `config/local.ini.php` gespeichert und überschreiben etwaige, zugehörige Umgebungsvariablen. + +- `-H|--dbhost ` Der Host der MySQL/MariaDB Datenbank (env `MYSQL_HOST`) +- `-p|--dbport ` Der Port der MySQL/MariaDB Datenbank (env `MYSQL_PORT`) +- `-U|--dbuser ` Der Benutzername des MySQL/MariaDB Datenbanklogins (env `MYSQL_USER` or `MYSQL_USERNAME`) +- `-P|--dbpass ` Das Passwort der MySQL/MariaDB Datenbanklogins (env `MYSQL_PASSWORD`) +- `-d|--dbdata ` Der Name der MySQL/MariaDB Datenbank (env `MYSQL_DATABASE`) +- `-b|--phppath ` Der Pfad zur PHP-Datei (env `FRIENDICA_PHP_PATH`) +- `-A|--admin ` Die Admin E-Mail Adresse dieses Friendica Knotens (env `FRIENDICA_ADMIN_MAIL`) +- `-T|--tz ` Die Zeitzone von Friendica (env `FRIENDICA_TZ`) +- `-L|--land ` Die Sprache von Friendica (env `FRIENDICA_LANG`) + +Gehe in den Friendica-Hauptordner und führe den Kommandozeilen Befehl aus: + + bin/console autoinstall [options] ### Einen Worker einrichten diff --git a/mod/install.php b/mod/install.php index fa20fd76cb..d2d322b3b9 100644 --- a/mod/install.php +++ b/mod/install.php @@ -26,8 +26,6 @@ function install_init(App $a) { $a->setConfigValue('system', 'value', '../install'); $a->theme['stylesheet'] = System::baseUrl()."/view/install/style.css"; - Install::setInstallMode(); - global $install_wizard_pass; if (x($_POST, 'pass')) { $install_wizard_pass = intval($_POST['pass']); diff --git a/src/App.php b/src/App.php index 55fa517342..2a5fba8541 100644 --- a/src/App.php +++ b/src/App.php @@ -174,40 +174,7 @@ class App $this->callstack['rendering'] = []; $this->callstack['parser'] = []; - // The order of the following calls is important to ensure proper initialization - $this->loadConfigFiles(); - - $this->loadDatabase(); - - $this->determineMode(); - - $this->determineUrlPath(); - - Config::load(); - - if ($this->mode & self::MODE_DBAVAILABLE) { - Core\Addon::loadHooks(); - - $this->loadAddonConfig(); - } - - $this->loadDefaultTimezone(); - - $this->page = [ - 'aside' => '', - 'bottom' => '', - 'content' => '', - 'end' => '', - 'footer' => '', - 'htmlhead' => '', - 'nav' => '', - 'page_title' => '', - 'right_aside' => '', - 'template' => '', - 'title' => '' - ]; - - $this->process_id = System::processID('log'); + $this->reload(); set_time_limit(0); @@ -314,6 +281,47 @@ class App $this->register_template_engine('Friendica\Render\FriendicaSmartyEngine'); } + /** + * Reloads the whole app instance + */ + public function reload() + { + // The order of the following calls is important to ensure proper initialization + $this->loadConfigFiles(); + + $this->loadDatabase(); + + $this->determineMode(); + + $this->determineUrlPath(); + + Config::load(); + + if ($this->mode & self::MODE_DBAVAILABLE) { + Core\Addon::loadHooks(); + + $this->loadAddonConfig(); + } + + $this->loadDefaultTimezone(); + + $this->page = [ + 'aside' => '', + 'bottom' => '', + 'content' => '', + 'end' => '', + 'footer' => '', + 'htmlhead' => '', + 'nav' => '', + 'page_title' => '', + 'right_aside' => '', + 'template' => '', + 'title' => '' + ]; + + $this->process_id = System::processID('log'); + } + /** * Load the configuration files * diff --git a/src/Core/Console/AutomaticInstallation.php b/src/Core/Console/AutomaticInstallation.php index a8489e7c8d..f0f3def2a0 100644 --- a/src/Core/Console/AutomaticInstallation.php +++ b/src/Core/Console/AutomaticInstallation.php @@ -35,24 +35,24 @@ Options -a All setup checks are required (except .htaccess) -f|--file prepared config file (e.g. "config/local.ini.php" itself) which will override every other config option - except the environment variables) -s|--savedb Save the DB credentials to the file (if environment variables is used) - -h|--dbhost The host of the mysql database (env MYSQL_HOST) - -p|--dbport The port of the mysql database (env MYSQL_PORT) - -d|--dbdata The name of the mysql database (env MYSQL_DATABASE) - -U|--dbuser The username of the mysql database login (env MYSQL_USER or MYSQL_USERNAME) - -P|--dbpass The password of the mysql database login (env MYSQL_PASSWORD) + -H|--dbhost The host of the mysql/mariadb database (env MYSQL_HOST) + -p|--dbport The port of the mysql/mariadb database (env MYSQL_PORT) + -d|--dbdata The name of the mysql/mariadb database (env MYSQL_DATABASE) + -U|--dbuser The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME) + -P|--dbpass The password of the mysql/mariadb database login (env MYSQL_PASSWORD) -b|--phppath The path of the PHP binary (env FRIENDICA_PHP_PATH) -A|--admin The admin email address of Friendica (env FRIENDICA_ADMIN_MAIL) -T|--tz The timezone of Friendica (env FRIENDICA_TZ) -L|--lang The language of Friendica (env FRIENDICA_LANG) Environment variables - MYSQL_HOST The host of the mysql database (mandatory if mysql and environment is used) - MYSQL_PORT The port of the mysql database - MYSQL_USERNAME|MYSQL_USER The username of the mysql database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb) - MYSQL_PASSWORD The password of the mysql database login - MYSQL_DATABASE The name of the mysql database + MYSQL_HOST The host of the mysql/mariadb database (mandatory if mysql and environment is used) + MYSQL_PORT The port of the mysql/mariadb database + MYSQL_USERNAME|MYSQL_USER The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb) + MYSQL_PASSWORD The password of the mysql/mariadb database login + MYSQL_DATABASE The name of the mysql/mariadb database FRIENDICA_PHP_PATH The path of the PHP binary - FRIENDICA_ADMIN_MAIL The admin email address of Friendica + FRIENDICA_ADMIN_MAIL The admin email address of Friendica (this email will be used for admin access) FRIENDICA_TZ The timezone of Friendica FRIENDICA_LANG The langauge of Friendica @@ -64,8 +64,7 @@ Examples Installs Friendica with environment variables and saves them to the 'config/local.ini.php' file bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica - Installs Friendica with a local mysql database with credentials - + Installs Friendica with a local mysql database with credentials HELP; } @@ -74,21 +73,20 @@ HELP; // Initialise the app $this->out("Initializing setup...\n"); + $a = BaseObject::getApp(); + // if a config file is set, $config_file = $this->getOption(['f', 'file']); if (!empty($config_file)) { - if ($config_file != 'config/local.ini.php') { + if ($config_file != 'config' . DIRECTORY_SEPARATOR . 'local.ini.php') { // Copy config file $this->out("Copying config file...\n"); - if (!copy($config_file, 'config/local.ini.php')) { - throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to 'config/local.ini.php' manually.\n"); + if (!copy($a->basepath . DIRECTORY_SEPARATOR . $config_file, $a->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php')) { + throw new RuntimeException("ERROR: Saving config file failed. Please copy '$config_file' to '$a->basepath" . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "local.ini.php' manually.\n"); } } - // load the app after copying the file - $a = BaseObject::getApp(); - $db_host = $a->getConfigValue('database', 'hostname'); $db_user = $a->getConfigValue('database', 'username'); $db_pass = $a->getConfigValue('database', 'password'); @@ -97,12 +95,9 @@ HELP; // Creating config file $this->out("Creating config file...\n"); - // load the app first (for the template engine) - $a = BaseObject::getApp(); - $save_db = $this->getOption(['s', 'savedb'], false); - $db_host = $this->getOption(['h', 'dbhost'], ($save_db) ? getenv('MYSQL_HOST') : ''); + $db_host = $this->getOption(['H', 'dbhost'], ($save_db) ? getenv('MYSQL_HOST') : ''); $db_port = $this->getOption(['p', 'dbport'], ($save_db) ? getenv('MYSQL_PORT') : null); $db_data = $this->getOption(['d', 'dbdata'], ($save_db) ? getenv('MYSQL_DATABASE') : ''); $db_user = $this->getOption(['U', 'dbuser'], ($save_db) ? getenv('MYSQL_USER') . getenv('MYSQL_USERNAME') : ''); @@ -112,12 +107,9 @@ HELP; $tz = $this->getOption(['T', 'tz'], (!empty('FRIENDICA_TZ')) ? getenv('FRIENDICA_TZ') : ''); $lang = $this->getOption(['L', 'lang'], (!empty('FRIENDICA_LANG')) ? getenv('FRIENDICA_LANG') : ''); - // creating config file - $this->out("Creating config file...\n"); - Install::createConfig( $php_path, - $db_host, + ((!empty($db_port)) ? $db_host . ':' . $db_port : $db_host), $db_user, $db_pass, $db_data, diff --git a/src/Core/Install.php b/src/Core/Install.php index e8f014618d..ba3a97ea6c 100644 --- a/src/Core/Install.php +++ b/src/Core/Install.php @@ -84,11 +84,12 @@ class Install extends BaseObject '$adminmail' => $adminmail, ]); - $result = file_put_contents('config/local.ini.php', $txt); + $app = self::getApp(); + + $result = file_put_contents($app->basepath . DIRECTORY_SEPARATOR . 'config' . DIRECTORY_SEPARATOR . 'local.ini.php', $txt); if (!$result) { - self::getApp()->data['txt'] = $txt; + $app->data['txt'] = $txt; } - } /** diff --git a/tests/src/Core/Console/AutomaticInstallationConsoleTest.php b/tests/src/Core/Console/AutomaticInstallationConsoleTest.php new file mode 100644 index 0000000000..79e379dcbc --- /dev/null +++ b/tests/src/Core/Console/AutomaticInstallationConsoleTest.php @@ -0,0 +1,333 @@ +root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')) { + $this->root->getChild('config') + ->removeChild('local.ini.php'); + } + + $this->db_host = getenv('MYSQL_HOST'); + $this->db_port = (!empty(getenv('MYSQL_PORT'))) ? getenv('MYSQL_PORT') : null; + $this->db_data = getenv('MYSQL_DATABASE'); + $this->db_user = getenv('MYSQL_USERNAME') . getenv('MYSQL_USER'); + $this->db_pass = getenv('MYSQL_PASSWORD'); + } + + private function assertConfig($family, $key, $value) + { + $config = $this->execute(['config', $family, $key]); + $this->assertEquals($family . "." . $key . " => " . $value . "\n", $config); + } + + private function assertFinished($txt, $withconfig = false, $copyfile = false) + { + $cfg = ''; + + if ($withconfig) { + $cfg = <<assertEquals($finished, $txt); + } + + private function assertStuckDB($txt) + { + $finished = <<assertEquals($finished, $txt); + } + + /** + * @medium + */ + public function testWithConfig() + { + $config = <<at($this->root) + ->setContent($config); + + $txt = $this->execute(['autoinstall', '-f', 'prepared.ini.php']); + + $this->assertFinished($txt, false, true); + + $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')); + } + + /** + * @medium + */ + public function testWithEnvironmentAndSave() + { + $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local')); + $this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin')); + $this->assertTrue(putenv('FRIENDICA_LANG=de')); + + $txt = $this->execute(['autoinstall', '--savedb']); + + $this->assertFinished($txt, true); + + $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')); + + $this->assertConfig('database', 'hostname', $this->db_host . (!empty($this->db_port) ? ':' . $this->db_port : '')); + $this->assertConfig('database', 'username', $this->db_user); + $this->assertConfig('database', 'database', $this->db_data); + $this->assertConfig('config', 'admin_email', 'admin@friendica.local'); + $this->assertConfig('system', 'default_timezone', 'Europe/Berlin'); + $this->assertConfig('system', 'language', 'de'); + } + + + /** + * @medium + */ + public function testWithEnvironmentWithoutSave() + { + $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local')); + $this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin')); + $this->assertTrue(putenv('FRIENDICA_LANG=de')); + + $txt = $this->execute(['autoinstall']); + + $this->assertFinished($txt, true); + + $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')); + + $this->assertConfig('database', 'hostname', ''); + $this->assertConfig('database', 'username', ''); + $this->assertConfig('database', 'database', ''); + $this->assertConfig('config', 'admin_email', 'admin@friendica.local'); + $this->assertConfig('system', 'default_timezone', 'Europe/Berlin'); + $this->assertConfig('system', 'language', 'de'); + } + + /** + * @medium + */ + public function testWithArguments() + { + $args = ['autoinstall']; + array_push($args, '--dbhost'); + array_push($args, $this->db_host); + array_push($args, '--dbuser'); + array_push($args, $this->db_user); + if (!empty($this->db_pass)) { + array_push($args, '--dbpass'); + array_push($args, $this->db_pass); + } + if (!empty($this->db_port)) { + array_push($args, '--dbport'); + array_push($args, $this->db_port); + } + array_push($args, '--dbdata'); + array_push($args, $this->db_data); + + array_push($args, '--admin'); + array_push($args, 'admin@friendica.local'); + array_push($args, '--tz'); + array_push($args, 'Europe/Berlin'); + array_push($args, '--lang'); + array_push($args, 'de'); + + $txt = $this->execute($args); + + $this->assertFinished($txt, true); + + $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')); + + $this->assertConfig('database', 'hostname', $this->db_host . (!empty($this->db_port) ? ':' . $this->db_port : '')); + $this->assertConfig('database', 'username', $this->db_user); + $this->assertConfig('database', 'database', $this->db_data); + $this->assertConfig('config', 'admin_email', 'admin@friendica.local'); + $this->assertConfig('system', 'default_timezone', 'Europe/Berlin'); + $this->assertConfig('system', 'language', 'de'); + } + + public function testNoDatabaseConnection() + { + $this->assertTrue(putenv('MYSQL_USERNAME=')); + $this->assertTrue(putenv('MYSQL_PASSWORD=')); + $this->assertTrue(putenv('MYSQL_DATABASE=')); + + $txt = $this->execute(['autoinstall']); + + $this->assertStuckDB($txt); + } + + public function testGetHelp() + { + // Usable to purposely fail if new commands are added without taking tests into account + $theHelp = << prepared config file (e.g. "config/local.ini.php" itself) which will override every other config option - except the environment variables) + -s|--savedb Save the DB credentials to the file (if environment variables is used) + -H|--dbhost The host of the mysql/mariadb database (env MYSQL_HOST) + -p|--dbport The port of the mysql/mariadb database (env MYSQL_PORT) + -d|--dbdata The name of the mysql/mariadb database (env MYSQL_DATABASE) + -U|--dbuser The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME) + -P|--dbpass The password of the mysql/mariadb database login (env MYSQL_PASSWORD) + -b|--phppath The path of the PHP binary (env FRIENDICA_PHP_PATH) + -A|--admin The admin email address of Friendica (env FRIENDICA_ADMIN_MAIL) + -T|--tz The timezone of Friendica (env FRIENDICA_TZ) + -L|--lang The language of Friendica (env FRIENDICA_LANG) + +Environment variables + MYSQL_HOST The host of the mysql/mariadb database (mandatory if mysql and environment is used) + MYSQL_PORT The port of the mysql/mariadb database + MYSQL_USERNAME|MYSQL_USER The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb) + MYSQL_PASSWORD The password of the mysql/mariadb database login + MYSQL_DATABASE The name of the mysql/mariadb database + FRIENDICA_PHP_PATH The path of the PHP binary + FRIENDICA_ADMIN_MAIL The admin email address of Friendica (this email will be used for admin access) + FRIENDICA_TZ The timezone of Friendica + FRIENDICA_LANG The langauge of Friendica + +Examples + bin/console autoinstall -f 'input.ini.php + Installs Friendica with the prepared 'input.ini.php' file + + bin/console autoinstall --savedb + Installs Friendica with environment variables and saves them to the 'config/local.ini.php' file + + bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica + Installs Friendica with a local mysql database with credentials + +HELP; + + $txt = $this->execute(['autoinstall', '-h']); + + $this->assertEquals($txt, $theHelp); + } +} diff --git a/tests/src/Core/Console/ConfigConsoleTest.php b/tests/src/Core/Console/ConfigConsoleTest.php index 5512528dff..c4fd217770 100644 --- a/tests/src/Core/Console/ConfigConsoleTest.php +++ b/tests/src/Core/Console/ConfigConsoleTest.php @@ -19,12 +19,12 @@ class ConfigConsoleTest extends ConsoleTest } private function assertGet($family, $key, $value) { - $config = $this->execute([__FILE__, 'config', $family, $key]); + $config = $this->execute(['config', $family, $key]); $this->assertEquals($family . "." . $key . " => " . $value . "\n", $config); } private function assertSet($family, $key, $value) { - $config = $this->execute([__FILE__, 'config', $family, $key, $value]); + $config = $this->execute(['config', $family, $key, $value]); $this->assertEquals($family . "." . $key . " <= " . $value . "\n", $config); } @@ -41,13 +41,13 @@ class ConfigConsoleTest extends ConsoleTest $testArray = [1, 2, 3]; DBA::insert('config', ['cat' => 'config', 'k' => 'test', 'v' => serialize($testArray)]); - $txt = $this->execute([__FILE__, 'config', 'config', 'test', 'now']); + $txt = $this->execute(['config', 'config', 'test', 'now']); $this->assertEquals("[Error] config.test is an array and can't be set using this command.\n", $txt); } function testTooManyArguments() { - $txt = $this->execute([__FILE__, 'config', 'config', 'test', 'it', 'now']); + $txt = $this->execute(['config', 'config', 'test', 'it', 'now']); $assertion = '[Warning] Too many arguments'; $firstline = substr($txt, 0, strlen($assertion)); @@ -56,8 +56,9 @@ class ConfigConsoleTest extends ConsoleTest function testVerbose() { $this->assertSet('test', 'it', 'now'); + $executable = $this->getExecutablePath(); $assertion = <<app->basepath}/tests/src/Core/Console/ConfigConsoleTest.php +Executable: {$executable} Arguments: array ( 0 => 'config', 1 => 'test', @@ -66,7 +67,7 @@ Options: array ( 'v' => 1, ) Command: config -Executable: {$this->app->basepath}/tests/src/Core/Console/ConfigConsoleTest.php +Executable: {$executable} Class: Friendica\Core\Console\Config Arguments: array ( 0 => 'test', @@ -78,7 +79,7 @@ Options: array ( it => now CONF; - $txt = $this->execute([__FILE__, 'config', 'test', '-v']); + $txt = $this->execute(['config', 'test', '-v']); $this->assertEquals($assertion, $txt); } diff --git a/tests/src/Core/Console/ConsoleTest.php b/tests/src/Core/Console/ConsoleTest.php index fd09a79452..0cc5c63359 100644 --- a/tests/src/Core/Console/ConsoleTest.php +++ b/tests/src/Core/Console/ConsoleTest.php @@ -4,7 +4,10 @@ namespace Friendica\Test\src\Core\Console; use Friendica\App; use Friendica\BaseObject; +use Friendica\Database\DBA; use Friendica\Test\Util\Intercept; +use org\bovigo\vfs\vfsStream; +use org\bovigo\vfs\vfsStreamDirectory; use PHPUnit\Framework\TestCase; abstract class ConsoleTest extends TestCase @@ -18,6 +21,11 @@ abstract class ConsoleTest extends TestCase */ protected $app; + /** + * @var vfsStreamDirectory The Stream Directory + */ + protected $root; + protected $stdout; protected function setUp() @@ -30,12 +38,19 @@ abstract class ConsoleTest extends TestCase $this->markTestSkipped('Please set the MYSQL_* environment variables to your test database credentials.'); } + $this->setUpVfsDir(); + // Reusable App object - $this->app = BaseObject::getApp(); + $this->app = new App($this->root->url()); + BaseObject::setApp($this->app); $this->console = new MultiUseConsole(); } public function execute($args) { + DBA::disconnect(); + $this->app->reload(); + + array_unshift($args, $this->getExecutablePath()); Intercept::reset(); $this->console->reset(); $this->console->parseTestArgv($args); @@ -45,4 +60,48 @@ abstract class ConsoleTest extends TestCase Intercept::reset(); return $returnStr; } + + /** + * @return string returns the path to the console executable during tests + */ + protected function getExecutablePath() { + return $this->root->getChild('bin' . DIRECTORY_SEPARATOR . 'console.php')->url(); + } + + private function setUpVfsDir() { + // the used directories inside the App class + $structure = [ + 'config' => [], + 'bin' => [] + ]; + + // create a virtual directory and copy all needed files and folders to it + $this->root = vfsStream::setup('friendica', null, $structure); + + $this->setConfigFile('config.ini.php'); + $this->setConfigFile('settings.ini.php'); + $this->setConfigFile('local.ini.php'); + $this->setConfigFile('dbstructure.json'); + + // fake console.php for setting an executable + vfsStream::newFile('console.php') + ->at($this->root->getChild('bin')) + ->setContent('at($this->root->getChild('config')) + ->setContent(file_get_contents($file)); + } + } } -- 2.39.5