ConnectorTest.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php
  2. namespace React\Tests\Socket;
  3. use React\Socket\Connector;
  4. use React\Promise\Promise;
  5. class ConnectorTest extends TestCase
  6. {
  7. public function testConstructWithoutLoopAssignsLoopAutomatically()
  8. {
  9. $connector = new Connector();
  10. $ref = new \ReflectionProperty($connector, 'connectors');
  11. $ref->setAccessible(true);
  12. $connectors = $ref->getValue($connector);
  13. $ref = new \ReflectionProperty($connectors['tcp'], 'loop');
  14. $ref->setAccessible(true);
  15. $loop = $ref->getValue($connectors['tcp']);
  16. $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
  17. }
  18. public function testConstructWithLoopAssignsGivenLoop()
  19. {
  20. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  21. $connector = new Connector(array(), $loop);
  22. $ref = new \ReflectionProperty($connector, 'connectors');
  23. $ref->setAccessible(true);
  24. $connectors = $ref->getValue($connector);
  25. $ref = new \ReflectionProperty($connectors['tcp'], 'loop');
  26. $ref->setAccessible(true);
  27. $loop = $ref->getValue($connectors['tcp']);
  28. $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
  29. }
  30. public function testConstructWithContextAssignsGivenContext()
  31. {
  32. $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
  33. $connector = new Connector(array(
  34. 'tcp' => $tcp,
  35. 'dns' => false,
  36. 'timeout' => false
  37. ));
  38. $ref = new \ReflectionProperty($connector, 'connectors');
  39. $ref->setAccessible(true);
  40. $connectors = $ref->getValue($connector);
  41. $this->assertSame($tcp, $connectors['tcp']);
  42. }
  43. public function testConstructWithLegacyContextSignatureAssignsGivenContext()
  44. {
  45. $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
  46. $connector = new Connector(null, array(
  47. 'tcp' => $tcp,
  48. 'dns' => false,
  49. 'timeout' => false
  50. ));
  51. $ref = new \ReflectionProperty($connector, 'connectors');
  52. $ref->setAccessible(true);
  53. $connectors = $ref->getValue($connector);
  54. $this->assertSame($tcp, $connectors['tcp']);
  55. }
  56. public function testConstructWithLegacyLoopSignatureAssignsGivenLoop()
  57. {
  58. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  59. $connector = new Connector($loop);
  60. $ref = new \ReflectionProperty($connector, 'connectors');
  61. $ref->setAccessible(true);
  62. $connectors = $ref->getValue($connector);
  63. $ref = new \ReflectionProperty($connectors['tcp'], 'loop');
  64. $ref->setAccessible(true);
  65. $loop = $ref->getValue($connectors['tcp']);
  66. $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
  67. }
  68. public function testConstructWithInvalidContextThrows()
  69. {
  70. $this->setExpectedException('InvalidArgumentException');
  71. new Connector('foo');
  72. }
  73. public function testConstructWithInvalidLoopThrows()
  74. {
  75. $this->setExpectedException('InvalidArgumentException');
  76. new Connector(array(), 'foo');
  77. }
  78. public function testConstructWithContextTwiceThrows()
  79. {
  80. $this->setExpectedException('InvalidArgumentException');
  81. new Connector(array(), array());
  82. }
  83. public function testConstructWithLoopTwiceThrows()
  84. {
  85. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  86. $this->setExpectedException('InvalidArgumentException');
  87. new Connector($loop, $loop);
  88. }
  89. public function testConstructWithNullContextAndLoopThrows()
  90. {
  91. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  92. $this->setExpectedException('InvalidArgumentException');
  93. new Connector(null, $loop);
  94. }
  95. public function testConstructWithLoopAndNullContextThrows()
  96. {
  97. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  98. $this->setExpectedException('InvalidArgumentException');
  99. new Connector($loop, null);
  100. }
  101. public function testConnectorUsesTcpAsDefaultScheme()
  102. {
  103. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  104. $promise = new Promise(function () { });
  105. $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
  106. $tcp->expects($this->once())->method('connect')->with('127.0.0.1:80')->willReturn($promise);
  107. $connector = new Connector(array(
  108. 'tcp' => $tcp
  109. ), $loop);
  110. $connector->connect('127.0.0.1:80');
  111. }
  112. public function testConnectorPassedThroughHostnameIfDnsIsDisabled()
  113. {
  114. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  115. $promise = new Promise(function () { });
  116. $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
  117. $tcp->expects($this->once())->method('connect')->with('tcp://google.com:80')->willReturn($promise);
  118. $connector = new Connector(array(
  119. 'tcp' => $tcp,
  120. 'dns' => false
  121. ), $loop);
  122. $connector->connect('tcp://google.com:80');
  123. }
  124. public function testConnectorWithUnknownSchemeAlwaysFails()
  125. {
  126. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  127. $connector = new Connector(array(), $loop);
  128. $promise = $connector->connect('unknown://google.com:80');
  129. $promise->then(null, $this->expectCallableOnceWithException(
  130. 'RuntimeException',
  131. 'No connector available for URI scheme "unknown" (EINVAL)',
  132. defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)
  133. ));
  134. }
  135. public function testConnectorWithDisabledTcpDefaultSchemeAlwaysFails()
  136. {
  137. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  138. $connector = new Connector(array(
  139. 'tcp' => false
  140. ), $loop);
  141. $promise = $connector->connect('google.com:80');
  142. $promise->then(null, $this->expectCallableOnceWithException(
  143. 'RuntimeException',
  144. 'No connector available for URI scheme "tcp" (EINVAL)',
  145. defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)
  146. ));
  147. }
  148. public function testConnectorWithDisabledTcpSchemeAlwaysFails()
  149. {
  150. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  151. $connector = new Connector(array(
  152. 'tcp' => false
  153. ), $loop);
  154. $promise = $connector->connect('tcp://google.com:80');
  155. $promise->then(null, $this->expectCallableOnceWithException(
  156. 'RuntimeException',
  157. 'No connector available for URI scheme "tcp" (EINVAL)',
  158. defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)
  159. ));
  160. }
  161. public function testConnectorWithDisabledTlsSchemeAlwaysFails()
  162. {
  163. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  164. $connector = new Connector(array(
  165. 'tls' => false
  166. ), $loop);
  167. $promise = $connector->connect('tls://google.com:443');
  168. $promise->then(null, $this->expectCallableOnceWithException(
  169. 'RuntimeException',
  170. 'No connector available for URI scheme "tls" (EINVAL)',
  171. defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)
  172. ));
  173. }
  174. public function testConnectorWithDisabledUnixSchemeAlwaysFails()
  175. {
  176. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  177. $connector = new Connector(array(
  178. 'unix' => false
  179. ), $loop);
  180. $promise = $connector->connect('unix://demo.sock');
  181. $promise->then(null, $this->expectCallableOnceWithException(
  182. 'RuntimeException',
  183. 'No connector available for URI scheme "unix" (EINVAL)',
  184. defined('SOCKET_EINVAL') ? SOCKET_EINVAL : (defined('PCNTL_EINVAL') ? PCNTL_EINVAL : 22)
  185. ));
  186. }
  187. public function testConnectorUsesGivenResolverInstance()
  188. {
  189. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  190. $promise = new Promise(function () { });
  191. $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock();
  192. $resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise);
  193. $connector = new Connector(array(
  194. 'dns' => $resolver,
  195. 'happy_eyeballs' => false,
  196. ), $loop);
  197. $connector->connect('google.com:80');
  198. }
  199. public function testConnectorUsesResolvedHostnameIfDnsIsUsed()
  200. {
  201. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  202. $promise = new Promise(function ($resolve) { $resolve('127.0.0.1'); });
  203. $resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock();
  204. $resolver->expects($this->once())->method('resolve')->with('google.com')->willReturn($promise);
  205. $promise = new Promise(function () { });
  206. $tcp = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
  207. $tcp->expects($this->once())->method('connect')->with('tcp://127.0.0.1:80?hostname=google.com')->willReturn($promise);
  208. $connector = new Connector(array(
  209. 'tcp' => $tcp,
  210. 'dns' => $resolver,
  211. 'happy_eyeballs' => false,
  212. ), $loop);
  213. $connector->connect('tcp://google.com:80');
  214. }
  215. }