feature: Unit test to validate the db schema (#6367)

* Unit test to validate the db schema
Changes build-schema.php to just write misc/db_schema.yaml

* Only build base if needed
Fix 178.sql

* Database is always created by init.php
add dbSchema test too, should guard against testing against an empty database

* feature: support non-standard unix socket (#5724)

* Add support for custom MySQL unix-socket

* NULL must be lowercase!

* Naive edit of html/install.php

* fixup

* Refactor dbConnect
Use it everywhere

* $config needs to be global
Don't need to set $database_link

* small cleanups

* Connect to the database for every test.

* travis fix for blank line
This commit is contained in:
Tony Murray 2017-04-07 09:07:44 -05:00 committed by Neil Lathwood
parent b1a414e785
commit b1483e3d2e
7 changed files with 73 additions and 29 deletions

View File

@ -1,5 +1,7 @@
sudo: required
language: php
services:
- mysql
matrix:
fast_finish: true
include:
@ -11,7 +13,7 @@ matrix:
- php: 5.5
env: SKIP_STYLE_CHECK=1
- php: 5.6
env: SKIP_STYLE_CHECK=1 EXECUTE_BUILD_DOCS=true EXECUTE_BUILD_SCHEMA=true
env: SKIP_STYLE_CHECK=1 EXECUTE_BUILD_DOCS=true EXECUTE_BUILD_SCHEMA=false
# - php: hhvm
# env: SKIP_STYLE_CHECK=1
@ -27,6 +29,7 @@ cache:
before_install:
- sudo apt-get -qq update
- sudo apt-get install -y snmp
- mysql -e 'CREATE DATABASE librenms_phpunit_78hunjuybybh;'
install:
- composer install --prefer-dist --no-interaction

View File

@ -28,5 +28,9 @@ if (getenv('DBTEST')) {
sleep(60);//Sleep for 60 seconds to ensure db work has completed
}
$output = dump_db_schema();
echo Symfony\Component\Yaml\Yaml::dump($output, 3, 2);
$file = $install_dir . '/misc/db_schema.yaml';
$yaml = Symfony\Component\Yaml\Yaml::dump(dump_db_schema(), 3, 2);
if (file_put_contents($file, $yaml)) {
echo "Updated!\n";
}

View File

@ -2,7 +2,7 @@
GH_REPO="@github.com/librenms/librenms.git"
FULL_REPO="https://${GH_TOKEN}:x-oauth-basic$GH_REPO"
DBTEST=1 ./scripts/build-schema.php > misc/db_schema.yaml
DBTEST=1 ./scripts/build-schema.php
STATUS=$(git status -s misc/db_schema.yaml)
if [[ "$STATUS" != "" ]]; then

View File

@ -1 +1 @@
ALTER TABLE `users` MODIFY `updated_at` TIMESTAMP;
ALTER TABLE `users` MODIFY `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;

View File

@ -29,45 +29,33 @@ use PHPUnit_Framework_ExpectationFailedException as PHPUnitException;
class DBSetupTest extends \PHPUnit_Framework_TestCase
{
private static $schema;
private static $sql_mode;
private static $db_created;
protected $backupGlobals = false;
public static function setUpBeforeClass()
{
if (getenv('DBTEST')) {
global $config;
self::$sql_mode = dbFetchCell("SELECT @@global.sql_mode as sql_mode");
dbQuery("SET NAMES 'utf8'");
dbQuery("SET CHARACTER SET 'utf8'");
dbQuery("SET COLLATION_CONNECTION = 'utf8_unicode_ci'");
self::$db_created = dbQuery("CREATE DATABASE " . $config['db_name'] . " CHARACTER SET utf8 COLLATE utf8_unicode_ci");
dbQuery("SET GLOBAL sql_mode='ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'");
dbQuery("USE " . $config['db_name']);
$build_base = $config['install_dir'] . '/build-base.php';
exec($build_base, $schema);
self::$schema = $schema;
}
//
}
public static function tearDownAfterClass()
{
if (getenv('DBTEST')) {
global $config;
global $config, $empty_db;
dbQuery("SET GLOBAL sql_mode='" . self::$sql_mode . "'");
if (self::$db_created) {
if ($empty_db) {
dbQuery("DROP DATABASE " . $config['db_name']);
}
}
}
public function setUp()
{
dbConnect();
}
public function testSetupDB()
{
if (getenv('DBTEST')) {
foreach (self::$schema as $output) {
global $schema;
foreach ($schema as $output) {
if (preg_match('/([1-9]+) errors/', $output) || preg_match('/Cannot execute query/', $output)) {
throw new PHPUnitException("Errors loading DB Schema: " . $output);
}
@ -75,6 +63,21 @@ class DBSetupTest extends \PHPUnit_Framework_TestCase
}
}
public function testSchema()
{
if (getenv('DBTEST')) {
global $config;
$schema = (int)@dbFetchCell('SELECT `version` FROM `dbSchema` LIMIT 1');
$this->assertGreaterThan(0, $schema, "Database has no schema!");
$files = glob($config['install_dir'] . '/sql-schema/*.sql');
end($files);
$expected = (int)basename(current($files), '.sql');
$this->assertEquals($expected, $schema, 'Schema not fully up-to-date');
}
}
public function testCheckDBCollation()
{
global $config;
@ -114,4 +117,20 @@ class DBSetupTest extends \PHPUnit_Framework_TestCase
$this->assertEmpty($collation, 'Wrong Column Collation or Character set: ' . $error);
}
}
public function testValidateSchema()
{
if (is_file('misc/db_schema.yaml')) {
$master_schema = \Symfony\Component\Yaml\Yaml::parse(
file_get_contents('misc/db_schema.yaml')
);
$current_schema = dump_db_schema();
$message = "Schema does not match the excpected schema defined by misc/db_schema.yaml\n";
$message .= "If you have changed the schema, make sure you update it with ./scripts/build-schema.php\n";
$this->assertEquals($master_schema, $current_schema, $message);
}
}
}

View File

@ -23,6 +23,8 @@
* @author Tony Murray <murraytony@gmail.com>
*/
global $config;
$install_dir = realpath(__DIR__ . '/..');
$init_modules = array('web');
@ -42,3 +44,19 @@ chdir($install_dir);
ini_set('display_errors', 1);
error_reporting(E_ALL & ~E_WARNING);
if (getenv('DBTEST')) {
global $empty_db, $schema;
$sql_mode = dbFetchCell("SELECT @@global.sql_mode as sql_mode");
$empty_db = (dbFetchCell("SELECT count(*) FROM `information_schema`.`tables` WHERE `table_type` = 'BASE TABLE' AND `table_schema` = ?", array($config['db_name'])) == 0);
dbQuery("SET GLOBAL sql_mode='ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'");
if ($empty_db) {
$cmd = $config['install_dir'] . '/build-base.php';
} else {
$cmd = '/usr/bin/env php ' . $config['install_dir'] . '/includes/sql-schema/update.php';
}
exec($cmd, $schema);
}

View File

@ -3,7 +3,7 @@
## Have a look in includes/defaults.inc.php for examples of settings you can set here. DO NOT EDIT defaults.inc.php!
### Database config
$config['db_host'] = 'localhost';
$config['db_host'] = '127.0.0.1';
$config['db_user'] = 'root';
$config['db_pass'] = '';
$config['db_name'] = 'librenms_phpunit_78hunjuybybh';