2017-02-07 15:08:52 +00:00
< ? php
/**
* DBSetup . php
*
* - Description -
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2021-02-08 23:29:04 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2017-02-07 15:08:52 +00:00
*
2021-02-08 23:29:04 +00:00
* @ link https :// www . librenms . org
2021-09-10 18:09:53 +00:00
*
2017-02-07 15:08:52 +00:00
* @ copyright 2017 Neil Lathwood
* @ author Neil Lathwood < librenms + n @ laf . io >
*/
namespace LibreNMS\Tests ;
2020-05-22 21:49:21 +00:00
use Artisan ;
use DB ;
2020-11-06 00:19:15 +00:00
use LibreNMS\DB\Schema ;
2017-02-07 15:08:52 +00:00
2017-04-26 12:56:00 +00:00
class DBSetupTest extends DBTestCase
2017-02-07 15:08:52 +00:00
{
2019-03-13 04:59:03 +00:00
protected $db_name ;
2020-05-22 21:49:21 +00:00
protected $connection = 'testing' ;
2019-03-13 04:59:03 +00:00
2020-05-19 14:31:50 +00:00
protected function setUp () : void
2019-03-13 04:59:03 +00:00
{
parent :: setUp ();
2020-05-22 21:49:21 +00:00
$this -> db_name = DB :: connection ( $this -> connection ) -> getDatabaseName ();
2019-03-13 04:59:03 +00:00
}
2017-02-07 15:08:52 +00:00
public function testSetupDB ()
{
2020-05-22 21:49:21 +00:00
$result = Artisan :: call ( 'migrate:fresh' , [
'--seed' => true ,
'--env' => 'testing' ,
'--database' => $this -> connection ,
]);
2019-02-12 23:45:04 +00:00
2020-05-22 21:49:21 +00:00
$this -> assertSame ( 0 , $result , 'Errors loading DB Schema: ' . Artisan :: output ());
2017-02-07 15:08:52 +00:00
}
2017-02-27 18:28:01 +00:00
2017-05-04 20:14:14 +00:00
public function testSchemaFiles ()
{
2020-05-22 21:49:21 +00:00
$files = glob ( base_path ( '/sql-schema/*.sql' ));
$this -> assertCount ( 282 , $files , 'You should not create new legacy schema files.' );
2017-05-04 20:14:14 +00:00
}
2017-04-07 14:07:44 +00:00
public function testSchema ()
{
2019-01-14 12:44:23 +00:00
$files = array_map ( function ( $migration_file ) {
return basename ( $migration_file , '.php' );
2021-03-13 00:10:14 +00:00
}, array_diff ( scandir ( base_path ( '/database/migrations' )), [ '.' , '..' , '.gitkeep' ]));
2020-05-22 21:49:21 +00:00
$migrated = DB :: connection ( $this -> connection ) -> table ( 'migrations' ) -> pluck ( 'migration' ) -> toArray ();
2019-01-14 12:44:23 +00:00
sort ( $files );
sort ( $migrated );
$this -> assertEquals ( $files , $migrated , 'List of run migrations did not match existing migration files.' );
2020-05-22 21:49:21 +00:00
// check legacy schema version is 1000
$schema = DB :: connection ( $this -> connection ) -> table ( 'dbSchema' )
-> orderBy ( 'version' , 'DESC' )
-> value ( 'version' );
2019-01-14 12:44:23 +00:00
$this -> assertEquals ( 1000 , $schema , 'Seed not run, after seed legacy dbSchema should be 1000' );
2017-04-07 14:07:44 +00:00
}
2017-02-27 18:28:01 +00:00
public function testCheckDBCollation ()
{
2021-03-28 14:23:08 +00:00
$collation = DB :: connection ( $this -> connection ) -> select ( DB :: raw ( " SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA S WHERE schema_name = ' $this->db_name ' AND ( DEFAULT_CHARACTER_SET_NAME != 'utf8mb4' OR DEFAULT_COLLATION_NAME != 'utf8mb4_unicode_ci') " ));
2017-04-13 10:05:14 +00:00
if ( isset ( $collation [ 0 ])) {
2021-03-28 14:23:08 +00:00
$error = implode ( ' ' , ( array ) $collation [ 0 ]);
2017-04-13 10:05:14 +00:00
} else {
$error = '' ;
2017-02-27 18:28:01 +00:00
}
2017-04-13 10:05:14 +00:00
$this -> assertEmpty ( $collation , 'Wrong Database Collation or Character set: ' . $error );
2017-02-27 18:28:01 +00:00
}
public function testCheckTableCollation ()
{
2021-03-28 14:23:08 +00:00
$collation = DB :: connection ( $this -> connection ) -> select ( DB :: raw ( " SELECT T.TABLE_NAME, C.CHARACTER_SET_NAME, C.COLLATION_NAME FROM information_schema.TABLES AS T, information_schema.COLLATION_CHARACTER_SET_APPLICABILITY AS C WHERE C.collation_name = T.table_collation AND T.table_schema = ' $this->db_name ' AND ( C.CHARACTER_SET_NAME != 'utf8mb4' OR C.COLLATION_NAME != 'utf8mb4_unicode_ci' ); " ));
2017-04-13 10:05:14 +00:00
$error = '' ;
2021-03-28 14:23:08 +00:00
foreach ( $collation as $data ) {
$error .= implode ( ' ' , ( array ) $data ) . PHP_EOL ;
2017-02-27 18:28:01 +00:00
}
2017-04-13 10:05:14 +00:00
$this -> assertEmpty ( $collation , 'Wrong Table Collation or Character set: ' . $error );
2017-02-27 18:28:01 +00:00
}
public function testCheckColumnCollation ()
{
2021-03-28 14:23:08 +00:00
$collation = DB :: connection ( $this -> connection ) -> select ( DB :: raw ( " SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ' $this->db_name ' AND ( CHARACTER_SET_NAME != 'utf8mb4' OR COLLATION_NAME != 'utf8mb4_unicode_ci' ); " ));
2017-04-13 10:05:14 +00:00
$error = '' ;
2021-03-28 14:23:08 +00:00
foreach ( $collation as $data ) {
$error .= implode ( ' ' , ( array ) $data ) . PHP_EOL ;
2017-02-27 18:28:01 +00:00
}
2017-04-13 10:05:14 +00:00
$this -> assertEmpty ( $collation , 'Wrong Column Collation or Character set: ' . $error );
}
public function testSqlMode ()
{
2021-03-28 21:55:41 +00:00
$result = DB :: connection ( $this -> connection ) -> selectOne ( DB :: raw ( 'SELECT @@version AS version, @@sql_mode AS mode' ));
preg_match ( '/([0-9.]+)(?:-(\w+))?/' , $result -> version , $matches );
$version = $matches [ 1 ] ? ? null ;
$vendor = $matches [ 2 ] ? ? null ;
$mode = $result -> mode ;
// NO_AUTO_CREATE_USER is removed in mysql 8
2022-03-06 18:52:50 +00:00
$expected = (
( $vendor !== 'MariaDB' && version_compare ( $version , '8.0.0' ) >= 0 ) ||
( $vendor == 'MariaDB' && version_compare ( $version , '10.5.15' ) >= 0 ))
2021-03-28 21:55:41 +00:00
? 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
: 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
$this -> assertEquals ( $expected , $mode );
2017-02-27 18:28:01 +00:00
}
2017-04-07 14:07:44 +00:00
public function testValidateSchema ()
{
if ( is_file ( 'misc/db_schema.yaml' )) {
2021-05-14 22:55:15 +00:00
DB :: connection ( $this -> connection ) -> statement ( 'SET time_zone = "+00:00";' );
2017-04-07 14:07:44 +00:00
$master_schema = \Symfony\Component\Yaml\Yaml :: parse (
file_get_contents ( 'misc/db_schema.yaml' )
);
2020-11-06 00:19:15 +00:00
$current_schema = Schema :: dump ( $this -> connection );
2017-04-07 14:07:44 +00:00
2020-05-22 21:49:21 +00:00
$message = " Schema does not match the expected schema defined by misc/db_schema.yaml \n " ;
2020-11-06 00:19:15 +00:00
$message .= " If you have changed the schema, make sure you update it with: lnms schema:dump \n " ;
2017-04-07 14:07:44 +00:00
$this -> assertEquals ( $master_schema , $current_schema , $message );
}
}
2017-02-07 15:08:52 +00:00
}