SecureServerTest.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php
  2. namespace React\Tests\Socket;
  3. use React\Socket\SecureServer;
  4. use React\Socket\TcpServer;
  5. use React\Promise\Promise;
  6. class SecureServerTest extends TestCase
  7. {
  8. /**
  9. * @before
  10. */
  11. public function setUpSkipTest()
  12. {
  13. if (defined('HHVM_VERSION')) {
  14. $this->markTestSkipped('Not supported on legacy HHVM');
  15. }
  16. }
  17. public function testConstructWithoutLoopAssignsLoopAutomatically()
  18. {
  19. $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
  20. $server = new SecureServer($tcp);
  21. $ref = new \ReflectionProperty($server, 'encryption');
  22. $ref->setAccessible(true);
  23. $encryption = $ref->getValue($server);
  24. $ref = new \ReflectionProperty($encryption, 'loop');
  25. $ref->setAccessible(true);
  26. $loop = $ref->getValue($encryption);
  27. $this->assertInstanceOf('React\EventLoop\LoopInterface', $loop);
  28. }
  29. public function testGetAddressWillBePassedThroughToTcpServer()
  30. {
  31. $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
  32. $tcp->expects($this->once())->method('getAddress')->willReturn('tcp://127.0.0.1:1234');
  33. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  34. $server = new SecureServer($tcp, $loop, array());
  35. $this->assertEquals('tls://127.0.0.1:1234', $server->getAddress());
  36. }
  37. public function testGetAddressWillReturnNullIfTcpServerReturnsNull()
  38. {
  39. $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
  40. $tcp->expects($this->once())->method('getAddress')->willReturn(null);
  41. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  42. $server = new SecureServer($tcp, $loop, array());
  43. $this->assertNull($server->getAddress());
  44. }
  45. public function testPauseWillBePassedThroughToTcpServer()
  46. {
  47. $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
  48. $tcp->expects($this->once())->method('pause');
  49. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  50. $server = new SecureServer($tcp, $loop, array());
  51. $server->pause();
  52. }
  53. public function testResumeWillBePassedThroughToTcpServer()
  54. {
  55. $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
  56. $tcp->expects($this->once())->method('resume');
  57. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  58. $server = new SecureServer($tcp, $loop, array());
  59. $server->resume();
  60. }
  61. public function testCloseWillBePassedThroughToTcpServer()
  62. {
  63. $tcp = $this->getMockBuilder('React\Socket\ServerInterface')->getMock();
  64. $tcp->expects($this->once())->method('close');
  65. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  66. $server = new SecureServer($tcp, $loop, array());
  67. $server->close();
  68. }
  69. public function testConnectionWillBeClosedWithErrorIfItIsNotAStream()
  70. {
  71. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  72. $tcp = new TcpServer(0, $loop);
  73. $connection = $this->getMockBuilder('React\Socket\ConnectionInterface')->getMock();
  74. $connection->expects($this->once())->method('close');
  75. $server = new SecureServer($tcp, $loop, array());
  76. $server->on('error', $this->expectCallableOnce());
  77. $tcp->emit('connection', array($connection));
  78. }
  79. public function testConnectionWillTryToEnableEncryptionAndWaitForHandshake()
  80. {
  81. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  82. $tcp = new TcpServer(0, $loop);
  83. $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock();
  84. $connection->expects($this->once())->method('getRemoteAddress')->willReturn('tcp://127.0.0.1:1234');
  85. $connection->expects($this->never())->method('close');
  86. $server = new SecureServer($tcp, $loop, array());
  87. $pending = new Promise(function () { });
  88. $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock();
  89. $encryption->expects($this->once())->method('enable')->willReturn($pending);
  90. $ref = new \ReflectionProperty($server, 'encryption');
  91. $ref->setAccessible(true);
  92. $ref->setValue($server, $encryption);
  93. $ref = new \ReflectionProperty($server, 'context');
  94. $ref->setAccessible(true);
  95. $ref->setValue($server, array());
  96. $server->on('error', $this->expectCallableNever());
  97. $server->on('connection', $this->expectCallableNever());
  98. $tcp->emit('connection', array($connection));
  99. }
  100. public function testConnectionWillBeClosedWithErrorIfEnablingEncryptionFails()
  101. {
  102. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  103. $tcp = new TcpServer(0, $loop);
  104. $connection = $this->getMockBuilder('React\Socket\Connection')->disableOriginalConstructor()->getMock();
  105. $connection->expects($this->once())->method('getRemoteAddress')->willReturn('tcp://127.0.0.1:1234');
  106. $connection->expects($this->once())->method('close');
  107. $server = new SecureServer($tcp, $loop, array());
  108. $error = new \RuntimeException('Original');
  109. $encryption = $this->getMockBuilder('React\Socket\StreamEncryption')->disableOriginalConstructor()->getMock();
  110. $encryption->expects($this->once())->method('enable')->willReturn(\React\Promise\reject($error));
  111. $ref = new \ReflectionProperty($server, 'encryption');
  112. $ref->setAccessible(true);
  113. $ref->setValue($server, $encryption);
  114. $ref = new \ReflectionProperty($server, 'context');
  115. $ref->setAccessible(true);
  116. $ref->setValue($server, array());
  117. $error = null;
  118. $server->on('error', $this->expectCallableOnce());
  119. $server->on('error', function ($e) use (&$error) {
  120. $error = $e;
  121. });
  122. $tcp->emit('connection', array($connection));
  123. $this->assertInstanceOf('RuntimeException', $error);
  124. $this->assertEquals('Connection from tcp://127.0.0.1:1234 failed during TLS handshake: Original', $error->getMessage());
  125. }
  126. public function testSocketErrorWillBeForwarded()
  127. {
  128. $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
  129. $tcp = new TcpServer(0, $loop);
  130. $server = new SecureServer($tcp, $loop, array());
  131. $server->on('error', $this->expectCallableOnce());
  132. $tcp->emit('error', array(new \RuntimeException('test')));
  133. }
  134. }