clientRunner.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. use GuzzleHttp\Psr7\Message;
  3. use GuzzleHttp\Psr7\Uri;
  4. use Ratchet\RFC6455\Handshake\InvalidPermessageDeflateOptionsException;
  5. use Ratchet\RFC6455\Handshake\PermessageDeflateOptions;
  6. use Ratchet\RFC6455\Messaging\MessageBuffer;
  7. use Ratchet\RFC6455\Handshake\ClientNegotiator;
  8. use Ratchet\RFC6455\Messaging\CloseFrameChecker;
  9. use Ratchet\RFC6455\Messaging\MessageInterface;
  10. use React\Promise\Deferred;
  11. use Ratchet\RFC6455\Messaging\Frame;
  12. use React\Socket\ConnectionInterface;
  13. use React\Socket\Connector;
  14. require __DIR__ . '/../bootstrap.php';
  15. define('AGENT', 'RatchetRFC/0.3');
  16. $testServer = $argc > 1 ? $argv[1] : "127.0.0.1";
  17. $loop = React\EventLoop\Factory::create();
  18. $connector = new Connector($loop);
  19. function echoStreamerFactory($conn, $permessageDeflateOptions = null)
  20. {
  21. $permessageDeflateOptions = $permessageDeflateOptions ?: PermessageDeflateOptions::createDisabled();
  22. return new \Ratchet\RFC6455\Messaging\MessageBuffer(
  23. new \Ratchet\RFC6455\Messaging\CloseFrameChecker,
  24. function (\Ratchet\RFC6455\Messaging\MessageInterface $msg, MessageBuffer $messageBuffer) use ($conn) {
  25. $messageBuffer->sendMessage($msg->getPayload(), true, $msg->isBinary());
  26. },
  27. function (\Ratchet\RFC6455\Messaging\FrameInterface $frame, MessageBuffer $messageBuffer) use ($conn) {
  28. switch ($frame->getOpcode()) {
  29. case Frame::OP_PING:
  30. return $conn->write((new Frame($frame->getPayload(), true, Frame::OP_PONG))->maskPayload()->getContents());
  31. break;
  32. case Frame::OP_CLOSE:
  33. return $conn->end((new Frame($frame->getPayload(), true, Frame::OP_CLOSE))->maskPayload()->getContents());
  34. break;
  35. }
  36. },
  37. false,
  38. null,
  39. null,
  40. null,
  41. [$conn, 'write'],
  42. $permessageDeflateOptions
  43. );
  44. }
  45. function getTestCases() {
  46. global $testServer;
  47. global $connector;
  48. $deferred = new Deferred();
  49. $connector->connect($testServer . ':9002')->then(function (ConnectionInterface $connection) use ($deferred, $testServer) {
  50. $cn = new ClientNegotiator();
  51. $cnRequest = $cn->generateRequest(new Uri('ws://' . $testServer . ':9002/getCaseCount'));
  52. $rawResponse = "";
  53. $response = null;
  54. /** @var MessageBuffer $ms */
  55. $ms = null;
  56. $connection->on('data', function ($data) use ($connection, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context, $cnRequest) {
  57. if ($response === null) {
  58. $rawResponse .= $data;
  59. $pos = strpos($rawResponse, "\r\n\r\n");
  60. if ($pos) {
  61. $data = substr($rawResponse, $pos + 4);
  62. $rawResponse = substr($rawResponse, 0, $pos + 4);
  63. $response = Message::parseResponse($rawResponse);
  64. if (!$cn->validateResponse($cnRequest, $response)) {
  65. $connection->end();
  66. $deferred->reject();
  67. } else {
  68. $ms = new MessageBuffer(
  69. new CloseFrameChecker,
  70. function (MessageInterface $msg) use ($deferred, $connection) {
  71. $deferred->resolve($msg->getPayload());
  72. $connection->close();
  73. },
  74. null,
  75. false,
  76. null,
  77. null,
  78. null,
  79. function () {}
  80. );
  81. }
  82. }
  83. }
  84. // feed the message streamer
  85. if ($ms) {
  86. $ms->onData($data);
  87. }
  88. });
  89. $connection->write(Message::toString($cnRequest));
  90. });
  91. return $deferred->promise();
  92. }
  93. $cn = new \Ratchet\RFC6455\Handshake\ClientNegotiator(
  94. PermessageDeflateOptions::permessageDeflateSupported() ? PermessageDeflateOptions::createEnabled() : null);
  95. function runTest($case)
  96. {
  97. global $connector;
  98. global $testServer;
  99. global $cn;
  100. $casePath = "/runCase?case={$case}&agent=" . AGENT;
  101. $deferred = new Deferred();
  102. $connector->connect($testServer . ':9002')->then(function (ConnectionInterface $connection) use ($deferred, $casePath, $case, $testServer) {
  103. $cn = new ClientNegotiator(
  104. PermessageDeflateOptions::permessageDeflateSupported() ? PermessageDeflateOptions::createEnabled() : null);
  105. $cnRequest = $cn->generateRequest(new Uri('ws://' . $testServer . ':9002' . $casePath));
  106. $rawResponse = "";
  107. $response = null;
  108. $ms = null;
  109. $connection->on('data', function ($data) use ($connection, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context, $cnRequest) {
  110. if ($response === null) {
  111. $rawResponse .= $data;
  112. $pos = strpos($rawResponse, "\r\n\r\n");
  113. if ($pos) {
  114. $data = substr($rawResponse, $pos + 4);
  115. $rawResponse = substr($rawResponse, 0, $pos + 4);
  116. $response = Message::parseResponse($rawResponse);
  117. if (!$cn->validateResponse($cnRequest, $response)) {
  118. echo "Invalid response.\n";
  119. $connection->end();
  120. $deferred->reject();
  121. } else {
  122. try {
  123. $permessageDeflateOptions = PermessageDeflateOptions::fromRequestOrResponse($response)[0];
  124. $ms = echoStreamerFactory(
  125. $connection,
  126. $permessageDeflateOptions
  127. );
  128. } catch (InvalidPermessageDeflateOptionsException $e) {
  129. $connection->end();
  130. }
  131. }
  132. }
  133. }
  134. // feed the message streamer
  135. if ($ms) {
  136. $ms->onData($data);
  137. }
  138. });
  139. $connection->on('close', function () use ($deferred) {
  140. $deferred->resolve();
  141. });
  142. $connection->write(Message::toString($cnRequest));
  143. });
  144. return $deferred->promise();
  145. }
  146. function createReport() {
  147. global $connector;
  148. global $testServer;
  149. $deferred = new Deferred();
  150. $connector->connect($testServer . ':9002')->then(function (ConnectionInterface $connection) use ($deferred, $testServer) {
  151. // $reportPath = "/updateReports?agent=" . AGENT . "&shutdownOnComplete=true";
  152. // we will stop it using docker now instead of just shutting down
  153. $reportPath = "/updateReports?agent=" . AGENT;
  154. $cn = new ClientNegotiator();
  155. $cnRequest = $cn->generateRequest(new Uri('ws://' . $testServer . ':9002' . $reportPath));
  156. $rawResponse = "";
  157. $response = null;
  158. /** @var MessageBuffer $ms */
  159. $ms = null;
  160. $connection->on('data', function ($data) use ($connection, &$rawResponse, &$response, &$ms, $cn, $deferred, &$context, $cnRequest) {
  161. if ($response === null) {
  162. $rawResponse .= $data;
  163. $pos = strpos($rawResponse, "\r\n\r\n");
  164. if ($pos) {
  165. $data = substr($rawResponse, $pos + 4);
  166. $rawResponse = substr($rawResponse, 0, $pos + 4);
  167. $response = Message::parseResponse($rawResponse);
  168. if (!$cn->validateResponse($cnRequest, $response)) {
  169. $connection->end();
  170. $deferred->reject();
  171. } else {
  172. $ms = new MessageBuffer(
  173. new CloseFrameChecker,
  174. function (MessageInterface $msg) use ($deferred, $connection) {
  175. $deferred->resolve($msg->getPayload());
  176. $connection->close();
  177. },
  178. null,
  179. false,
  180. null,
  181. null,
  182. null,
  183. function () {}
  184. );
  185. }
  186. }
  187. }
  188. // feed the message streamer
  189. if ($ms) {
  190. $ms->onData($data);
  191. }
  192. });
  193. $connection->write(Message::toString($cnRequest));
  194. });
  195. return $deferred->promise();
  196. }
  197. $testPromises = [];
  198. getTestCases()->then(function ($count) use ($loop) {
  199. $allDeferred = new Deferred();
  200. $runNextCase = function () use (&$i, &$runNextCase, $count, $allDeferred) {
  201. $i++;
  202. if ($i > $count) {
  203. $allDeferred->resolve();
  204. return;
  205. }
  206. echo "Running test $i/$count...";
  207. $startTime = microtime(true);
  208. runTest($i)
  209. ->then(function () use ($startTime) {
  210. echo " completed " . round((microtime(true) - $startTime) * 1000) . " ms\n";
  211. })
  212. ->then($runNextCase);
  213. };
  214. $i = 0;
  215. $runNextCase();
  216. $allDeferred->promise()->then(function () {
  217. createReport();
  218. });
  219. });
  220. $loop->run();