Skip to content

Commit

Permalink
Adds config file validator and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hollodotme committed Aug 9, 2017
1 parent 4068eed commit 8612c1a
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 14 deletions.
12 changes: 7 additions & 5 deletions bin/endpoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use PHPMQ\Server\StreamListeners\MessageQueueServerListener;
use PHPMQ\Server\Validators\ArgumentValidator;
use PHPMQ\Server\Validators\CompositeValidator;
use PHPMQ\Server\Validators\ConfigFileValidator;
use PHPMQ\Server\Validators\PHPVersionValidator;

require __DIR__ . '/../vendor/autoload.php';
Expand All @@ -33,7 +34,8 @@

$validator->addValidators(
new PHPVersionValidator( $minPhpVersion, PHP_VERSION, PHP_BINARY, $packageVersion ),
new ArgumentValidator( $argv )
new ArgumentValidator( $argv ),
new ConfigFileValidator( $argv[1] ?? $defaultConfigFile )
);

if ( $validator->failed() )
Expand Down Expand Up @@ -76,10 +78,10 @@
catch ( \Throwable $e )
{
$cliWriter->clearScreen( 'FAILURE' )
->writeLn( '<fg:red>ERROR:<:fg> ' . $e->getMessage() )
->writeLn( 'Exception: ' . get_class( $e ) )
->writeLn( 'In file %s on line %s', $e->getFile(), (string)$e->getLine() )
->writeLn( $e->getTraceAsString() );
->writeLn( '<fg:red>ERROR:<:fg> ' . $e->getMessage() )
->writeLn( 'Exception: ' . get_class( $e ) )
->writeLn( 'In file %s on line %s', $e->getFile(), (string)$e->getLine() )
->writeLn( $e->getTraceAsString() );

fwrite( STDERR, $cliWriter->getOutput() );

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"extra": {
"tools": {
"phpunit": {
"url": "https://phar.phpunit.de/phpunit-6.2.3.phar",
"url": "https://phar.phpunit.de/phpunit-6.3.0.phar",
"only-dev": true
},
"coveralls": {
Expand Down
16 changes: 8 additions & 8 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

140 changes: 140 additions & 0 deletions src/Validators/ConfigFileValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?php declare(strict_types=1);
/**
* @author hollodotme
*/

namespace PHPMQ\Server\Validators;

use PHPMQ\Server\Validators\Interfaces\ValidatesEnvironment;

/**
* Class ConfigFileValidator
* @package PHPMQ\Server\Validators
*/
final class ConfigFileValidator implements ValidatesEnvironment
{
/** @var string */
private $configFilePath;

/** @var bool|\SimpleXMLElement */
private $xml;

/** @var bool */
private $passed = false;

/** @var array */
private $messages = [];

/** @var array|\LibXMLError[] */
private $xmlErrors = [];

public function __construct( string $configFilePath )
{
$this->configFilePath = $configFilePath;

libxml_use_internal_errors( true );

$this->xml = simplexml_load_file( $configFilePath );
$this->xmlErrors = libxml_get_errors();

libxml_use_internal_errors( false );
}

public function failed() : bool
{
$this->checkForParseErrors();

$this->passed && $this->checkMessageQueueServer();

return !$this->passed;
}

private function checkForParseErrors() : void
{
if ( $this->xml === false )
{
$this->addErrorMessage( 'Could not read configuration file: "%s". Parse errors:', $this->configFilePath );
$this->addXmlErrors();

return;
}

$this->passed = true;
}

private function addErrorMessage( string $format, ...$params ) : void
{
$this->messages[] = sprintf( '<bg:red>ERROR:<:bg> ' . $format, ...$params );
}

private function addXmlErrors() : void
{
/** @var \LibXMLError $xmlError */
foreach ( $this->xmlErrors as $xmlError )
{
$this->addErrorMessage(
'[%s] %s in line %d and column %d',
$xmlError->code,
$xmlError->message,
$xmlError->line,
$xmlError->column
);
}
}

private function checkMessageQueueServer() : void
{
$baseXPath = '/PHPMQ/servers/messagequeue';

if ( !$this->elementExists( $baseXPath ) )
{
$this->passed = false;
$this->addErrorMessage( 'Missing configuration part: servers/messagequeue' );

return;
}

$networkXPath = $baseXPath . '/network';
$unixXPath = $baseXPath . '/unix';

if ( !$this->elementExists( $networkXPath ) && !$this->elementExists( $unixXPath ) )
{
$this->passed = false;
$this->addErrorMessage( 'Invalid message queue server socket type. Allowed: network, unix' );

return;
}

$networkHostXPath = $networkXPath . '/config[@name="host"]';
$networkPortXPath = $networkXPath . '/config[@name="port"]';

if ( $this->elementExists( $networkXPath )
&& (!$this->elementExists( $networkHostXPath ) || !$this->elementExists( $networkPortXPath )) )
{
$this->passed = false;
$this->addErrorMessage( 'Invalid message queue server socket config. Host and port must be configured.' );

return;
}

$unixPathXPath = $unixXPath . '/config[@name="path"]';

if ( $this->elementExists( $unixXPath ) && !$this->elementExists( $unixPathXPath ) )
{
$this->passed = false;
$this->addErrorMessage( 'Invalid message queue server socket config. Path must be configured.' );

return;
}
}

private function elementExists( string $xpath ) : bool
{
return (count( $this->xml->xpath( $xpath ) ) >= 1);
}

public function getMessages() : array
{
return $this->messages;
}
}
64 changes: 64 additions & 0 deletions tests/Unit/Validators/ConfigFileValidatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php declare(strict_types=1);
/**
* @author hollodotme
*/

namespace PHPMQ\Server\Tests\Unit\Validators;

use PHPMQ\Server\Validators\ConfigFileValidator;
use PHPUnit\Framework\TestCase;

/**
* Class ConfigFileValidatorTest
* @package PHPMQ\Server\Tests\Unit\Validators
*/
final class ConfigFileValidatorTest extends TestCase
{
public function testValidationFailsForBrokenXmlConfigFile() : void
{
$validator = new ConfigFileValidator( __DIR__ . '/Fixtures/broken.xml' );

$this->assertTrue( $validator->failed() );
$this->assertNotEmpty( $validator->getMessages() );
}

public function testValidationFailsNotForValidXmlConfigFile() : void
{
$validator = new ConfigFileValidator( __DIR__ . '/Fixtures/valid.xml' );

$this->assertFalse( $validator->failed() );
$this->assertEmpty( $validator->getMessages() );
}

public function testFailsIfMessageQueueServerIsNotConfigured() : void
{
$validator = new ConfigFileValidator( __DIR__ . '/Fixtures/missing-message-queue-server.xml' );

$this->assertTrue( $validator->failed() );
$this->assertNotEmpty( $validator->getMessages() );
}

public function testFailsIfMessageQueueServerSocketTypeIsInvalid() : void
{
$validator = new ConfigFileValidator( __DIR__ . '/Fixtures/invalid-message-queue-server-socket-type.xml' );

$this->assertTrue( $validator->failed() );
$this->assertNotEmpty( $validator->getMessages() );
}

public function testFailsIfMessageQueueServerNetworkSocketIsInvalid() : void
{
$validator = new ConfigFileValidator( __DIR__ . '/Fixtures/invalid-message-queue-server-network-socket.xml' );

$this->assertTrue( $validator->failed() );
$this->assertNotEmpty( $validator->getMessages() );
}

public function testFailsIfMessageQueueServerUnixSocketIsInvalid() : void
{
$validator = new ConfigFileValidator( __DIR__ . '/Fixtures/invalid-message-queue-server-unix-socket.xml' );

$this->assertTrue( $validator->failed() );
$this->assertNotEmpty( $validator->getMessages() );
}
}
4 changes: 4 additions & 0 deletions tests/Unit/Validators/Fixtures/broken.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<PHPMQ>
<Broken>
</PHPMQ>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<PHPMQ>
<servers>
<messagequeue>
<network/>
</messagequeue>
</servers>
</PHPMQ>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<PHPMQ>
<servers>
<messagequeue>
<invalid/>
</messagequeue>
</servers>
</PHPMQ>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<PHPMQ>
<servers>
<messagequeue>
<unix/>
</messagequeue>
</servers>
</PHPMQ>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" ?>
<PHPMQ>
<servers/>
</PHPMQ>
11 changes: 11 additions & 0 deletions tests/Unit/Validators/Fixtures/valid.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<PHPMQ>
<servers>
<messagequeue>
<network>
<config name="host" value="192.168.3.13"/>
<config name="port" value="9100"/>
</network>
</messagequeue>
</servers>
</PHPMQ>

0 comments on commit 8612c1a

Please sign in to comment.