Fixup tests for new MessageStreamer

This commit is contained in:
matt 2015-12-26 14:31:45 -05:00
parent 1579666238
commit c31bea9f30
11 changed files with 198 additions and 129 deletions

24
.travis.yml Normal file
View File

@ -0,0 +1,24 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- 7
- hhvm
matrix:
allow_failures:
- php: hhvm
before_install:
- export PATH=$HOME/.local/bin:$PATH
- pip install autobahntestsuite --user `whoami`
- pip list autobahntestsuite --user `whoami`
before_script:
- composer install
- sh tests/ab/run_ab_tests.sh
script:
- phpunit

27
phpunit.xml.dist Normal file
View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
forceCoversAnnotation="true"
mapTestClassNameToCoveredClassName="true"
bootstrap="tests/bootstrap.php"
colors="true"
backupGlobals="false"
backupStaticAttributes="false"
syntaxCheck="false"
stopOnError="false"
>
<testsuites>
<testsuite name="tests">
<directory>tests</directory>
<exclude>
<directory>test/ab</directory>
</exclude>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>./src/</directory>
</whitelist>
</filter>
</phpunit>

28
tests/AbResultsTest.php Normal file
View File

@ -0,0 +1,28 @@
<?php
namespace Ratchet\RFC6455\Test;
class AbResultsTest extends TestCase
{
private function verifyAutobahnResults($fileName)
{
$this->assertFileExists($fileName);
$resultsJson = file_get_contents($fileName);
$results = json_decode($resultsJson);
$agentName = array_keys(get_object_vars($results))[0];
foreach ($results->$agentName as $name => $result) {
if ($result->behavior === "INFORMATIONAL") {
continue;
}
$this->assertTrue(in_array($result->behavior, ["OK", "NON-STRICT"]), "Autobahn test case " . $name . " in " . $fileName);
}
}
public function testAutobahnClientResults()
{
$this->verifyAutobahnResults(__DIR__ . '/ab/reports/clients/index.json');
}
public function testAutobahnServerResults()
{
$this->verifyAutobahnResults(__DIR__ . '/ab/reports/servers/index.json');
}
}

8
tests/TestCase.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace Ratchet\RFC6455\Test;
class TestCase extends \PHPUnit_Framework_TestCase
{
}

View File

@ -1,67 +0,0 @@
<?php
class AbConnectionContext implements Ratchet\RFC6455\Messaging\Streaming\ContextInterface {
private $_frame;
private $_message;
protected $maskPayload;
/**
* @var \React\Stream\Stream
*/
protected $_conn;
public function __construct(\React\Stream\Stream $connectionContext, $maskPayload = false) {
$this->_conn = $connectionContext;
$this->maskPayload = $maskPayload;
}
public function setFrame(\Ratchet\RFC6455\Messaging\Protocol\FrameInterface $frame = null) {
$this->_frame = $frame;
}
public function getFrame() {
return $this->_frame;
}
public function setMessage(\Ratchet\RFC6455\Messaging\Protocol\MessageInterface $message = null) {
$this->_message = $message;
}
public function getMessage() {
return $this->_message;
}
public function onMessage(\Ratchet\RFC6455\Messaging\Protocol\MessageInterface $msg) {
$frame = new \Ratchet\RFC6455\Messaging\Protocol\Frame($msg->getPayload(), true, $msg[0]->getOpcode());
if ($this->maskPayload) {
$frame->maskPayload();
}
$this->_conn->write($frame->getContents());
}
public function onPing(\Ratchet\RFC6455\Messaging\Protocol\FrameInterface $frame) {
$pong = new \Ratchet\RFC6455\Messaging\Protocol\Frame($frame->getPayload(), true, \Ratchet\RFC6455\Messaging\Protocol\Frame::OP_PONG);
if ($this->maskPayload) {
$pong->maskPayload();
}
$this->_conn->write($pong->getContents());
}
public function onPong(\Ratchet\RFC6455\Messaging\Protocol\FrameInterface $msg) {
// TODO: Implement onPong() method.
}
public function onClose($code = 1000) {
$frame = new \Ratchet\RFC6455\Messaging\Protocol\Frame(
pack('n', $code),
true,
\Ratchet\RFC6455\Messaging\Protocol\Frame::OP_CLOSE
);
if ($this->maskPayload) {
$frame->maskPayload();
}
$this->_conn->end($frame->getContents());
}
}

View File

@ -4,34 +4,11 @@ use Ratchet\RFC6455\Messaging\Protocol\Frame;
use Ratchet\RFC6455\Messaging\Protocol\Message; use Ratchet\RFC6455\Messaging\Protocol\Message;
require __DIR__ . '/../bootstrap.php'; require __DIR__ . '/../bootstrap.php';
require __DIR__ . '/AbConnectionContext.php';
define('AGENT', 'RatchetRFC/0.0.0'); define('AGENT', 'RatchetRFC/0.0.0');
$testServer = "127.0.0.1"; $testServer = "127.0.0.1";
class EmConnectionContext extends AbConnectionContext implements \Evenement\EventEmitterInterface, Ratchet\RFC6455\Messaging\Streaming\ContextInterface {
use \Evenement\EventEmitterTrait;
public function onMessage(\Ratchet\RFC6455\Messaging\Protocol\MessageInterface $msg) {
$this->emit('message', [$msg]);
}
public function sendMessage(Frame $frame) {
if ($this->maskPayload) {
$frame->maskPayload();
}
$this->_conn->write($frame->getContents());
}
public function close($closeCode = Frame::CLOSE_NORMAL) {
$closeFrame = new Frame(pack('n', $closeCode), true, Frame::OP_CLOSE);
$closeFrame->maskPayload();
$this->_conn->end($closeFrame->getContents());
}
}
$loop = React\EventLoop\Factory::create(); $loop = React\EventLoop\Factory::create();
$dnsResolverFactory = new React\Dns\Resolver\Factory(); $dnsResolverFactory = new React\Dns\Resolver\Factory();
@ -39,6 +16,32 @@ $dnsResolver = $dnsResolverFactory->createCached('8.8.8.8', $loop);
$factory = new \React\SocketClient\Connector($loop, $dnsResolver); $factory = new \React\SocketClient\Connector($loop, $dnsResolver);
function echoStreamerFactory($conn)
{
return new \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer(
new \Ratchet\RFC6455\Encoding\Validator,
new \Ratchet\RFC6455\Messaging\Protocol\CloseFrameChecker,
function (\Ratchet\RFC6455\Messaging\Protocol\MessageInterface $msg) use ($conn) {
/** @var Frame $frame */
foreach ($msg as $frame) {
$frame->maskPayload();
}
$conn->write($msg->getContents());
},
function (\Ratchet\RFC6455\Messaging\Protocol\FrameInterface $frame) use ($conn) {
switch ($frame->getOpcode()) {
case Frame::OP_PING:
return $conn->write((new Frame($frame->getPayload(), true, Frame::OP_PONG))->maskPayload()->getContents());
break;
case Frame::OP_CLOSE:
return $conn->end((new Frame($frame->getPayload(), true, Frame::OP_CLOSE))->maskPayload()->getContents());
break;
}
},
false
);
}
function getTestCases() { function getTestCases() {
global $factory; global $factory;
global $testServer; global $testServer;
@ -52,12 +55,10 @@ function getTestCases() {
$rawResponse = ""; $rawResponse = "";
$response = null; $response = null;
$ms = new \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer(new \Ratchet\RFC6455\Encoding\Validator(), true); /** @var \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer $ms */
$ms = null;
/** @var EmConnectionContext $context */ $stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context) {
$context = null;
$stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, $ms, $cn, $deferred, &$context) {
if ($response === null) { if ($response === null) {
$rawResponse .= $data; $rawResponse .= $data;
$pos = strpos($rawResponse, "\r\n\r\n"); $pos = strpos($rawResponse, "\r\n\r\n");
@ -70,19 +71,23 @@ function getTestCases() {
$stream->end(); $stream->end();
$deferred->reject(); $deferred->reject();
} else { } else {
$context = new EmConnectionContext($stream, true); $ms = new \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer(
new \Ratchet\RFC6455\Encoding\Validator,
$context->on('message', function (Message $msg) use ($stream, $deferred, $context) { new \Ratchet\RFC6455\Messaging\Protocol\CloseFrameChecker,
$deferred->resolve($msg->getPayload()); function (\Ratchet\RFC6455\Messaging\Protocol\MessageInterface $msg) use ($deferred, $stream) {
$context->close(); $deferred->resolve($msg->getPayload());
}); $stream->close();
},
null,
false
);
} }
} }
} }
// feed the message streamer // feed the message streamer
if ($response && $context) { if ($ms) {
$ms->onData($data, $context); $ms->onData($data);
} }
}); });
@ -108,12 +113,9 @@ function runTest($case)
$rawResponse = ""; $rawResponse = "";
$response = null; $response = null;
$ms = new \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer(new \Ratchet\RFC6455\Encoding\Validator(), true); $ms = null;
/** @var AbConnectionContext $context */ $stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context) {
$context = null;
$stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, $ms, $cn, $deferred, &$context) {
if ($response === null) { if ($response === null) {
$rawResponse .= $data; $rawResponse .= $data;
$pos = strpos($rawResponse, "\r\n\r\n"); $pos = strpos($rawResponse, "\r\n\r\n");
@ -126,14 +128,14 @@ function runTest($case)
$stream->end(); $stream->end();
$deferred->reject(); $deferred->reject();
} else { } else {
$context = new AbConnectionContext($stream, true); $ms = echoStreamerFactory($stream);
} }
} }
} }
// feed the message streamer // feed the message streamer
if ($response && $context) { if ($ms) {
$ms->onData($data, $context); $ms->onData($data);
} }
}); });
@ -154,18 +156,17 @@ function createReport() {
$deferred = new Deferred(); $deferred = new Deferred();
$factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred) { $factory->create($testServer, 9001)->then(function (\React\Stream\Stream $stream) use ($deferred) {
$cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator('/updateReports?agent=' . AGENT); $reportPath = "/updateReports?agent=" . AGENT . "&shutdownOnComplete=true";
$cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator($reportPath);
$cnRequest = $cn->getRequest(); $cnRequest = $cn->getRequest();
$rawResponse = ""; $rawResponse = "";
$response = null; $response = null;
$ms = new \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer(new \Ratchet\RFC6455\Encoding\Validator(), true); /** @var \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer $ms */
$ms = null;
/** @var EmConnectionContext $context */ $stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context) {
$context = null;
$stream->on('data', function ($data) use ($stream, &$rawResponse, &$response, $ms, $cn, $deferred, &$context) {
if ($response === null) { if ($response === null) {
$rawResponse .= $data; $rawResponse .= $data;
$pos = strpos($rawResponse, "\r\n\r\n"); $pos = strpos($rawResponse, "\r\n\r\n");
@ -178,19 +179,23 @@ function createReport() {
$stream->end(); $stream->end();
$deferred->reject(); $deferred->reject();
} else { } else {
$context = new EmConnectionContext($stream, true); $ms = new \Ratchet\RFC6455\Messaging\Streaming\MessageStreamer(
new \Ratchet\RFC6455\Encoding\Validator,
$context->on('message', function (Message $msg) use ($stream, $deferred, $context) { new \Ratchet\RFC6455\Messaging\Protocol\CloseFrameChecker,
$deferred->resolve($msg->getPayload()); function (\Ratchet\RFC6455\Messaging\Protocol\MessageInterface $msg) use ($deferred, $stream) {
$context->close(); $deferred->resolve($msg->getPayload());
}); $stream->close();
},
null,
false
);
} }
} }
} }
// feed the message streamer // feed the message streamer
if ($response && $context) { if ($ms) {
$ms->onData($data, $context); $ms->onData($data);
} }
}); });

View File

@ -0,0 +1,13 @@
{
"options": {"failByDrop": false},
"outdir": "./reports/servers",
"servers": [
{"agent": "RatchetRFC/0.0.0",
"url": "ws://localhost:9001",
"options": {"version": 18}}
],
"cases": ["1.*", "2.*", "3.*", "4.*", "5.*", "6.*", "7.*"],
"exclude-cases": [],
"exclude-agent-cases": {}
}

View File

@ -0,0 +1,10 @@
{
"url": "ws://127.0.0.1:9001"
, "options": {
"failByDrop": false
}
, "outdir": "./reports/clients"
, "cases": ["1.*", "2.*", "3.*", "4.*", "5.*", "6.*", "7.*"]
, "exclude-cases": []
, "exclude-agent-cases": {}
}

12
tests/ab/run_ab_tests.sh Normal file
View File

@ -0,0 +1,12 @@
cd tests/ab
wstest -m fuzzingserver -s fuzzingserver.travis.json &
sleep 5
php clientRunner.php
sleep 2
php startServer.php 25 &
sleep 3
wstest -m fuzzingclient -s fuzzingclient.travis.json
sleep 2

View File

@ -6,6 +6,14 @@ use Ratchet\RFC6455\Messaging\Protocol\Frame;
require_once __DIR__ . "/../bootstrap.php"; require_once __DIR__ . "/../bootstrap.php";
$loop = \React\EventLoop\Factory::create(); $loop = \React\EventLoop\Factory::create();
if ($argc > 1 && is_numeric($argv[1])) {
echo "Setting test server to stop in " . $argv[1] . " seconds.\n";
$loop->addTimer($argv[1], function () {
exit;
});
}
$socket = new \React\Socket\Server($loop); $socket = new \React\Socket\Server($loop);
$server = new \React\Http\Server($socket); $server = new \React\Http\Server($socket);

View File

@ -4,15 +4,16 @@
* Find the auto loader file * Find the auto loader file
*/ */
$files = [ $files = [
__DIR__ . '/../../../../vendor/autoload.php',
__DIR__ . '/../../../vendor/autoload.php',
__DIR__ . '/../../vendor/autoload.php',
__DIR__ . '/../vendor/autoload.php', __DIR__ . '/../vendor/autoload.php',
__DIR__ . '/../../vendor/autoload.php',
__DIR__ . '/../../../vendor/autoload.php',
__DIR__ . '/../../../../vendor/autoload.php',
]; ];
foreach ($files as $file) { foreach ($files as $file) {
if (file_exists($file)) { if (file_exists($file)) {
require $file; $loader = require $file;
$loader->addPsr4('Ratchet\\RFC6455\\Test\\', __DIR__);
break; break;
} }
} }