/test/Blackbox/AnnounceTest.php

https://gitlab.com/hwmack/LibtorrentPHP · PHP · 198 lines · 158 code · 26 blank · 14 comment · 1 complexity · 2cb2a0e08daf6eeb4a7be4bc03b7ec59 MD5 · raw file

  1. <?php
  2. namespace CWE\Libraries\LibtorrentPHP\Test\Blackbox;
  3. use CWE\Libraries\LibtorrentPHP\Persistence\SqlPersistence;
  4. use CWE\Libraries\LibtorrentPHP\Core;
  5. use CWE\Libraries\Bencode;
  6. class AnnounceTest extends \PHPUnit_Framework_TestCase
  7. {
  8. private $persistence;
  9. const CLIENT_IP = '123.123.123.123';
  10. const CLIENT_PORT = '555';
  11. const CLIENT_PORT_COMPACT = "\x02\x2B";
  12. const ANNOUNCE_INTERVAL = 60;
  13. const INFO_HASH = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
  14. const PEER_ID = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
  15. const SEED_PEER_ID = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\2";
  16. const SEED_IP = '124.124.124.124';
  17. const SEED_IP_COMPACT = "\x7c\x7c\x7c\x7c";
  18. const LEECH_PEER_ID = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3";
  19. const LEECH_IP = '125.125.125.125';
  20. const LEECH_IP_COMPACT = "\x7d\x7d\x7d\x7d";
  21. public function setUp()
  22. {
  23. $this->setupDatabaseFixture();
  24. }
  25. /**
  26. * @requires pdo
  27. */
  28. public function testFirstAnnounce()
  29. {
  30. $core = new Core( $this->persistence );
  31. $get = array(
  32. 'info_hash' => self::INFO_HASH,
  33. 'peer_id' => self::PEER_ID,
  34. 'port' => self::CLIENT_PORT,
  35. 'uploaded' => 1024,
  36. 'downloaded' => 2048,
  37. 'left' => 4096,
  38. );
  39. $response = $core->announce( $get, self::CLIENT_IP, self::ANNOUNCE_INTERVAL );
  40. $parsed_response = $this->parseResponse( $response );
  41. $this->assertEquals( 0, $parsed_response['complete'] );
  42. $this->assertEquals( 0, $parsed_response['incomplete'] );
  43. $this->assertEquals( array(), $parsed_response['peers'] );
  44. $this->assertEquals(
  45. self::ANNOUNCE_INTERVAL,
  46. $parsed_response['interval']
  47. );
  48. }
  49. /**
  50. * @requires pdo
  51. */
  52. public function testAnnounceWithPeers()
  53. {
  54. $core = new Core( $this->persistence );
  55. $this->announceOtherPeers( $core );
  56. $get = array(
  57. 'info_hash' => self::INFO_HASH,
  58. 'peer_id' => self::PEER_ID,
  59. 'port' => self::CLIENT_PORT,
  60. 'uploaded' => 1024,
  61. 'downloaded' => 2048,
  62. 'left' => 4096,
  63. );
  64. $response = $core->announce( $get, self::CLIENT_IP, self::ANNOUNCE_INTERVAL );
  65. $parsed_response = $this->parseResponse( $response );
  66. $this->assertEquals( 1, $parsed_response['complete'] );
  67. $this->assertEquals( 1, $parsed_response['incomplete'] );
  68. $this->assertContains( array(
  69. // Using the same port for the other peers.
  70. 'ip' => self::SEED_IP,
  71. 'port' => self::CLIENT_PORT,
  72. 'peer id' => self::SEED_PEER_ID,
  73. ), $parsed_response['peers'] );
  74. $this->assertContains( array(
  75. // Using the same port for the other peers.
  76. 'ip' => self::LEECH_IP,
  77. 'port' => self::CLIENT_PORT,
  78. 'peer id' => self::LEECH_PEER_ID,
  79. ), $parsed_response['peers'] );
  80. $this->assertEquals(
  81. self::ANNOUNCE_INTERVAL,
  82. $parsed_response['interval']
  83. );
  84. }
  85. /**
  86. * @requires pdo
  87. */
  88. public function testAnnounceWithCompactPeers()
  89. {
  90. $core = new Core( $this->persistence );
  91. $this->announceOtherPeers( $core );
  92. $get = array(
  93. 'info_hash' => self::INFO_HASH,
  94. 'peer_id' => self::PEER_ID,
  95. 'port' => self::CLIENT_PORT,
  96. 'uploaded' => 1024,
  97. 'downloaded' => 2048,
  98. 'left' => 4096,
  99. 'compact' => 1,
  100. );
  101. $response = $core->announce( $get, self::CLIENT_IP, self::ANNOUNCE_INTERVAL );
  102. $parsed_response = $this->parseResponse( $response );
  103. $this->assertEquals( 1, $parsed_response['complete'] );
  104. $this->assertEquals( 1, $parsed_response['incomplete'] );
  105. $this->assertContains(
  106. self::SEED_IP_COMPACT . self::CLIENT_PORT_COMPACT,
  107. $parsed_response['peers']
  108. );
  109. $this->assertContains(
  110. self::LEECH_IP_COMPACT . self::CLIENT_PORT_COMPACT,
  111. $parsed_response['peers']
  112. );
  113. $this->assertEquals(
  114. self::ANNOUNCE_INTERVAL,
  115. $parsed_response['interval']
  116. );
  117. }
  118. private function setupDatabaseFixture()
  119. {
  120. // @todo: change to sqlite
  121. $table_definitions = file_get_contents(
  122. __DIR__ . '/../Fixtures/sqlite_tables.sql'
  123. );
  124. $driver = new \PDO( 'sqlite::memory:' );
  125. $statements = preg_split( '/;[ \t]*\n/', $table_definitions, -1, PREG_SPLIT_NO_EMPTY );
  126. foreach ( $statements as $statement )
  127. {
  128. if ( !$driver->query( $statement ) )
  129. {
  130. $this->fail(
  131. 'Could not set up database fixture: ' .
  132. var_export( $driver->errorInfo(), true )
  133. );
  134. }
  135. }
  136. $this->persistence = new SqlPersistence( $driver );
  137. }
  138. private function parseResponse( $response )
  139. {
  140. return Bencode::decode($response);
  141. }
  142. private function announceOtherPeers( $core )
  143. {
  144. // Announcing a seeder (testing update of peer as well).
  145. $core->announce( array(
  146. 'info_hash' => self::INFO_HASH,
  147. 'peer_id' => self::SEED_PEER_ID,
  148. 'port' => self::CLIENT_PORT,
  149. 'uploaded' => 0,
  150. 'downloaded' => 1024,
  151. 'left' => 0,
  152. ), self::SEED_IP, self::ANNOUNCE_INTERVAL );
  153. $core->announce( array(
  154. 'info_hash' => self::INFO_HASH,
  155. 'peer_id' => self::SEED_PEER_ID,
  156. 'port' => self::CLIENT_PORT,
  157. 'uploaded' => 0,
  158. 'downloaded' => 7168,
  159. 'left' => 6144,
  160. 'event' => 'completed'
  161. ), self::SEED_IP, self::ANNOUNCE_INTERVAL );
  162. // Announcing a leecher.
  163. $core->announce( array(
  164. 'info_hash' => self::INFO_HASH,
  165. 'peer_id' => self::LEECH_PEER_ID,
  166. 'port' => self::CLIENT_PORT,
  167. 'uploaded' => 1024,
  168. 'downloaded' => 2048,
  169. 'left' => 4096,
  170. ), self::LEECH_IP, self::ANNOUNCE_INTERVAL );
  171. }
  172. }