Skip to content

Commit

Permalink
feature: Unit test to validate the db schema (#6367)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
murrant authored and laf committed Apr 7, 2017
1 parent b1a414e commit b1483e3
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 29 deletions.
5 changes: 4 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
sudo: required
language: php
services:
- mysql
matrix:
fast_finish: true
include:
Expand All @@ -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

Expand All @@ -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
Expand Down
8 changes: 6 additions & 2 deletions scripts/build-schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,9 @@
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";
}
2 changes: 1 addition & 1 deletion scripts/deploy-schema.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion sql-schema/178.sql
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ALTER TABLE `users` MODIFY `updated_at` TIMESTAMP;
ALTER TABLE `users` MODIFY `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
65 changes: 42 additions & 23 deletions tests/DBSetupTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,52 +29,55 @@

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);
}
}
}
}

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;
Expand Down Expand Up @@ -114,4 +117,20 @@ public function testCheckColumnCollation()
$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);
}
}
}
18 changes: 18 additions & 0 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
* @author Tony Murray <murraytony@gmail.com>
*/

global $config;

$install_dir = realpath(__DIR__ . '/..');

$init_modules = array('web');
Expand All @@ -42,3 +44,19 @@

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);
}
2 changes: 1 addition & 1 deletion tests/config/config.test.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down

0 comments on commit b1483e3

Please sign in to comment.