diff --git a/.travis.yml b/.travis.yml index 64c93d3a8..465c0d807 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ env: global: - DEPENDENCIES=standard - APC=true - - TRAVIS_TEST_EXCLUDES="--exclude-group slow,jpgraph" + - TRAVIS_TEST_EXCLUDES="--exclude-group slow,jpgraph,pushserver" matrix: - DB=mysql - DB=pgsql @@ -30,7 +30,10 @@ matrix: include: # httpd-based - php: 5.4 - env: DB=mysql TEST_ADAPTER=HTTP + env: DB=mysql TEST_COMPONENT=HTTPD + # push-server + - php: 5.4 + env: DB=mysql TEST_COMPONENT=PUSH_SERVER # from..to - php: 5.4 env: DB=mysql DEPENDENCIES=lowest @@ -76,7 +79,7 @@ install: - if [ "$DEPENDENCIES" = "highest" ]; then composer update -n; fi - if [ "$JSLINT" = true ]; then npm install; fi - if [ "$SECURITY" = true ]; then wget http://get.sensiolabs.org/security-checker.phar; fi - - if [ "$TEST_ADAPTER" = "HTTP" ]; then composer require volkszaehler/httpd:dev-master jenssegers/proxy:~2.2; fi + - if [ "$TEST_COMPONENT" = "HTTPD" ]; then composer require volkszaehler/httpd:dev-master jenssegers/proxy:~2.2; fi # add apc cache - | @@ -100,7 +103,7 @@ before_script: - sed -i "s/'vz'/'$USER'/" etc/volkszaehler.conf.php - sed -i "s/'demo'/'$PASSWORD'/" etc/volkszaehler.conf.php - sed -i "s/'volkszaehler'/'$DATABASE'/" etc/volkszaehler.conf.php - - if [ "$DB" = "sqlite" ]; then sed -i "s/\?>/\$config['db']['path']\ =\ VZ_DIR.'\/sqlite.db3'\n?>/" etc/volkszaehler.conf.php; fi + - if [ "$DB" = "sqlite" ]; then sed -i "s/\?>/\$config['db']['path']\ =\ VZ_DIR.'\/sqlite.db3'\;\n?>/" etc/volkszaehler.conf.php; fi - cat etc/volkszaehler.conf.php # create database @@ -112,15 +115,21 @@ before_script: # setup local middleware - | - if [ "$TEST_ADAPTER" = "HTTP" ]; then - sed -i "s/testAdapter\" value=\".*\"/testAdapter\" value=\"$TEST_ADAPTER\"/" phpunit.xml + if [ "$TEST_COMPONENT" = "HTTPD" ]; then + sed -i "s/testAdapter\" value=\".*\"/testAdapter\" value=\"$TEST_COMPONENT\"/" phpunit.xml vendor/bin/httpd.php start & HTTPD_PID=$! echo "Started httpd with pid $HTTPD_PID" fi + # push server tests + - if [ "$TEST_COMPONENT" = "PUSH_SERVER" ]; then sed -i "s/\?>/\$config['push']['enabled']\ =\ true\;\n?>/" etc/volkszaehler.conf.php; fi + - if [ "$TEST_COMPONENT" = "PUSH_SERVER" ]; then + php misc/tools/push-server.php & + fi + after_script: - - if [ "$TEST_ADAPTER" = "HTTP" ]; then kill -9 $HTTPD_PID; fi + - if [ "$TEST_COMPONENT" = "HTTPD" ]; then kill -9 $HTTPD_PID; fi script: # run core tests @@ -129,7 +138,7 @@ script: # run aggregation tests (mysql only) - if [ "$DB" = "mysql" ]; then sed -i "s/\?>/\$config['aggregation']\ =\ true;\n?>/" etc/volkszaehler.conf.php; fi - | - if [ "$DB" = "mysql" -a "$TEST_ADAPTER" = "HTTP" ]; then + if [ "$DB" = "mysql" -a "$TEST_COMPONENT" = "HTTPD" ]; then kill -9 $HTTPD_PID sleep 10 vendor/bin/httpd.php start & @@ -141,6 +150,9 @@ script: # run aggregation tool itself (mysql only) - if [ "$DB" = "mysql" ]; then php misc/tools/aggregate.php run -m delta -l hour; fi + # push server tests + - if [ "$TEST_COMPONENT" = "PUSH_SERVER" ]; then phpunit --group pushserver; fi + # jslint javascript sources - if [ "$JSLINT" = true ]; then gulp jshint; fi diff --git a/lib/Server/MiddlewareAdapter.php b/lib/Server/MiddlewareAdapter.php index f26c320ba..96c19e757 100644 --- a/lib/Server/MiddlewareAdapter.php +++ b/lib/Server/MiddlewareAdapter.php @@ -45,11 +45,6 @@ class MiddlewareAdapter { */ protected $em; - /** - * @var EntityController - */ - protected $controller; - /** * @var array */ @@ -68,9 +63,8 @@ public function removeAdapter(PushTransportInterface $adapter) { } protected function openController($force = false) { - if ($force || $this->em == null || $this->controller == null || !$this->em->isOpen()) { + if ($force || $this->em == null || !$this->em->isOpen()) { $this->em = Router::createEntityManager(false); - $this->controller = new EntityController(new Request(), $this->em); } } @@ -78,7 +72,7 @@ protected function connectToMiddleware($uuid) { try { $this->openController(); - $entity = $this->controller->getSingleEntity($uuid); + $entity = EntityController::factory($this->em, $uuid); $class = $entity->getDefinition()->getInterpreter(); $interpreter = new $class($entity, $this->em, null, null); @@ -132,24 +126,27 @@ protected function convertRawTuple(Interpreter\Interpreter $interpreter, $tuple) * @return null|string Returns null on invalid request */ public function handlePushMessage($json) { - $msg = json_decode($json, true); $response = array( 'version' => VZ_VERSION, 'data' => array() ); // validate input message + if (null === ($msg = json_decode($json, true))) { + return null; + } if (null === ($data = @$msg['data']) || !is_array($data)) { return null; } // loop through channels foreach ($data as $channel) { + // validate channel structure if (null === ($uuid = @$channel['uuid'])) { - break; + return null; } if (null === ($tuples = @$channel['tuples']) || !is_array($tuples) || !count($tuples)) { - break; + return null; } // get interpreter if no client has connected yet @@ -161,6 +158,10 @@ public function handlePushMessage($json) { // convert raw tuples using interpreter rules $transformed = array(); foreach ($tuples as $tuple) { + if (!is_array($tuple) || count($tuple) < 2) { + return null; + } + if (count($tuple) < 3) { $tuple[] = 1; } diff --git a/phpunit.xml b/phpunit.xml index 8bf684f56..9c2b6f1bd 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -12,6 +12,7 @@ slow jpgraph + pushserver diff --git a/test/PushServerTest.php b/test/PushServerTest.php new file mode 100644 index 000000000..9ca85d343 --- /dev/null +++ b/test/PushServerTest.php @@ -0,0 +1,50 @@ + + */ + +namespace Tests; + +use Volkszaehler\Util; + +class PushServerTest extends Data +{ + // channel properties + static $resolution = 100; + + /** + * Create channel + */ + static function setupBeforeClass() { + parent::setupBeforeClass(); + self::$uuid = self::createChannel('Counter', 'electric meter', self::$resolution); + } + + /** + * @group pushserver + */ + function testPushMessage() { + $this->assertTrue(Util\Configuration::read('push.enabled'), 'Push server disabled'); + + $exitCode = null; + $port = Util\Configuration::read('push.server'); + $curl = "curl %s -s -m 3 -X POST -d '{\"data\":[{\"uuid\":\"%s\",\"tuples\":[[1,1,1]]}]}' localhost:%d 2>&1"; + + // run and test for failure + $cmd = sprintf($curl, '-f', self::$uuid, $port); + passthru($cmd, $exitCode); + + // run to get output + if ($exitCode !== 0) { + $cmd = sprintf($curl, '-i', self::$uuid, $port); + passthru($cmd); + } + + $this->assertTrue($exitCode === 0, sprintf('Curl failed with exit code %d', $exitCode)); + } +} + +?>