DHTMessageFactoryImplTest.cc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. #include "DHTMessageFactoryImpl.h"
  2. #include "Exception.h"
  3. #include "Util.h"
  4. #include "DHTNode.h"
  5. #include "DHTRoutingTable.h"
  6. #include "Dictionary.h"
  7. #include "Data.h"
  8. #include "List.h"
  9. #include "Peer.h"
  10. #include "PeerMessageUtil.h"
  11. #include "DHTBucket.h"
  12. #include "DHTPingMessage.h"
  13. #include "DHTPingReplyMessage.h"
  14. #include "DHTFindNodeMessage.h"
  15. #include "DHTFindNodeReplyMessage.h"
  16. #include "DHTGetPeersMessage.h"
  17. #include "DHTGetPeersReplyMessage.h"
  18. #include "DHTAnnouncePeerMessage.h"
  19. #include "DHTAnnouncePeerReplyMessage.h"
  20. #include <cppunit/extensions/HelperMacros.h>
  21. class DHTMessageFactoryImplTest:public CppUnit::TestFixture {
  22. CPPUNIT_TEST_SUITE(DHTMessageFactoryImplTest);
  23. CPPUNIT_TEST(testCreatePingMessage);
  24. CPPUNIT_TEST(testCreatePingReplyMessage);
  25. CPPUNIT_TEST(testCreateFindNodeMessage);
  26. CPPUNIT_TEST(testCreateFindNodeReplyMessage);
  27. CPPUNIT_TEST(testCreateGetPeersMessage);
  28. CPPUNIT_TEST(testCreateGetPeersReplyMessage_nodes);
  29. CPPUNIT_TEST(testCreateGetPeersReplyMessage_values);
  30. CPPUNIT_TEST(testCreateAnnouncePeerMessage);
  31. CPPUNIT_TEST(testCreateAnnouncePeerReplyMessage);
  32. CPPUNIT_TEST_SUITE_END();
  33. public:
  34. DHTMessageFactoryImplTest():factory(0), routingTable(0), localNode(0) {}
  35. DHTMessageFactoryImpl* factory;
  36. DHTRoutingTableHandle routingTable;
  37. DHTNodeHandle localNode;
  38. unsigned char transactionID[DHT_TRANSACTION_ID_LENGTH];
  39. unsigned char remoteNodeID[DHT_ID_LENGTH];
  40. void setUp()
  41. {
  42. localNode = new DHTNode();
  43. factory = new DHTMessageFactoryImpl();
  44. factory->setLocalNode(localNode);
  45. memset(transactionID, 0xff, DHT_TRANSACTION_ID_LENGTH);
  46. memset(remoteNodeID, 0x0f, DHT_ID_LENGTH);
  47. routingTable = new DHTRoutingTable(localNode);
  48. factory->setRoutingTable(routingTable);
  49. }
  50. void tearDown()
  51. {
  52. delete factory;
  53. }
  54. void testCreatePingMessage();
  55. void testCreatePingReplyMessage();
  56. void testCreateFindNodeMessage();
  57. void testCreateFindNodeReplyMessage();
  58. void testCreateGetPeersMessage();
  59. void testCreateGetPeersReplyMessage_nodes();
  60. void testCreateGetPeersReplyMessage_values();
  61. void testCreateAnnouncePeerMessage();
  62. void testCreateAnnouncePeerReplyMessage();
  63. };
  64. CPPUNIT_TEST_SUITE_REGISTRATION(DHTMessageFactoryImplTest);
  65. void DHTMessageFactoryImplTest::testCreatePingMessage()
  66. {
  67. SharedHandle<Dictionary> d = new Dictionary();
  68. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  69. d->put("y", new Data("q"));
  70. d->put("q", new Data("ping"));
  71. Dictionary* a = new Dictionary();
  72. a->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  73. d->put("a", a);
  74. SharedHandle<DHTPingMessage> m = factory->createQueryMessage(d.get(), "192.168.0.1", 6881);
  75. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  76. remoteNode->setIPAddress("192.168.0.1");
  77. remoteNode->setPort(6881);
  78. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  79. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  80. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  81. Util::toHex(m->getTransactionID()));
  82. }
  83. void DHTMessageFactoryImplTest::testCreatePingReplyMessage()
  84. {
  85. SharedHandle<Dictionary> d = new Dictionary();
  86. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  87. d->put("y", new Data("r"));
  88. Dictionary* r = new Dictionary();
  89. r->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  90. d->put("r", r);
  91. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  92. remoteNode->setIPAddress("192.168.0.1");
  93. remoteNode->setPort(6881);
  94. SharedHandle<DHTPingReplyMessage> m = factory->createResponseMessage("ping", d.get(), remoteNode);
  95. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  96. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  97. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  98. Util::toHex(m->getTransactionID()));
  99. }
  100. void DHTMessageFactoryImplTest::testCreateFindNodeMessage()
  101. {
  102. SharedHandle<Dictionary> d = new Dictionary();
  103. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  104. d->put("y", new Data("q"));
  105. d->put("q", new Data("find_node"));
  106. Dictionary* a = new Dictionary();
  107. a->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  108. unsigned char targetNodeID[DHT_ID_LENGTH];
  109. memset(targetNodeID, 0x11, DHT_ID_LENGTH);
  110. a->put("target", new Data(targetNodeID, DHT_ID_LENGTH));
  111. d->put("a", a);
  112. SharedHandle<DHTFindNodeMessage> m = factory->createQueryMessage(d.get(), "192.168.0.1", 6881);
  113. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  114. remoteNode->setIPAddress("192.168.0.1");
  115. remoteNode->setPort(6881);
  116. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  117. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  118. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  119. Util::toHex(m->getTransactionID()));
  120. CPPUNIT_ASSERT_EQUAL(Util::toHex(targetNodeID, DHT_ID_LENGTH),
  121. Util::toHex(m->getTargetNodeID(), DHT_ID_LENGTH));
  122. }
  123. void DHTMessageFactoryImplTest::testCreateFindNodeReplyMessage()
  124. {
  125. try {
  126. SharedHandle<Dictionary> d = new Dictionary();
  127. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  128. d->put("y", new Data("r"));
  129. Dictionary* r = new Dictionary();
  130. r->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  131. string compactNodeInfo;
  132. DHTNodeHandle nodes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  133. for(size_t i = 0; i < DHTBucket::K; ++i) {
  134. nodes[i] = new DHTNode();
  135. nodes[i]->setIPAddress("192.168.0."+Util::uitos(i+1));
  136. nodes[i]->setPort(6881+i);
  137. char buf[6];
  138. CPPUNIT_ASSERT(PeerMessageUtil::createcompact(buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
  139. compactNodeInfo +=
  140. string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
  141. string(&buf[0], &buf[sizeof(buf)]);
  142. }
  143. r->put("nodes", new Data(compactNodeInfo));
  144. d->put("r", r);
  145. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  146. remoteNode->setIPAddress("192.168.0.1");
  147. remoteNode->setPort(6881);
  148. SharedHandle<DHTFindNodeReplyMessage> m = factory->createResponseMessage("find_node", d.get(), remoteNode);
  149. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  150. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  151. CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
  152. CPPUNIT_ASSERT(nodes[0] == m->getClosestKNodes()[0]);
  153. CPPUNIT_ASSERT(nodes[7] == m->getClosestKNodes()[7]);
  154. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  155. Util::toHex(m->getTransactionID()));
  156. } catch(Exception* e) {
  157. cerr << *e << endl;
  158. CPPUNIT_FAIL("exception thrown.");
  159. }
  160. }
  161. void DHTMessageFactoryImplTest::testCreateGetPeersMessage()
  162. {
  163. SharedHandle<Dictionary> d = new Dictionary();
  164. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  165. d->put("y", new Data("q"));
  166. d->put("q", new Data("get_peers"));
  167. Dictionary* a = new Dictionary();
  168. a->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  169. unsigned char infoHash[DHT_ID_LENGTH];
  170. memset(infoHash, 0x11, DHT_ID_LENGTH);
  171. a->put("info_hash", new Data(infoHash, DHT_ID_LENGTH));
  172. d->put("a", a);
  173. SharedHandle<DHTGetPeersMessage> m = factory->createQueryMessage(d.get(), "192.168.0.1", 6881);
  174. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  175. remoteNode->setIPAddress("192.168.0.1");
  176. remoteNode->setPort(6881);
  177. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  178. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  179. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  180. Util::toHex(m->getTransactionID()));
  181. CPPUNIT_ASSERT_EQUAL(Util::toHex(infoHash, DHT_ID_LENGTH),
  182. Util::toHex(m->getInfoHash(), DHT_ID_LENGTH));
  183. }
  184. void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_nodes()
  185. {
  186. try {
  187. SharedHandle<Dictionary> d = new Dictionary();
  188. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  189. d->put("y", new Data("r"));
  190. Dictionary* r = new Dictionary();
  191. r->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  192. string compactNodeInfo;
  193. DHTNodeHandle nodes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  194. for(size_t i = 0; i < DHTBucket::K; ++i) {
  195. nodes[i] = new DHTNode();
  196. nodes[i]->setIPAddress("192.168.0."+Util::uitos(i+1));
  197. nodes[i]->setPort(6881+i);
  198. char buf[6];
  199. CPPUNIT_ASSERT(PeerMessageUtil::createcompact(buf, nodes[i]->getIPAddress(), nodes[i]->getPort()));
  200. compactNodeInfo +=
  201. string(&nodes[i]->getID()[0], &nodes[i]->getID()[DHT_ID_LENGTH])+
  202. string(&buf[0], &buf[sizeof(buf)]);
  203. }
  204. r->put("nodes", new Data(compactNodeInfo));
  205. r->put("token", new Data("token"));
  206. d->put("r", r);
  207. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  208. remoteNode->setIPAddress("192.168.0.1");
  209. remoteNode->setPort(6881);
  210. SharedHandle<DHTGetPeersReplyMessage> m = factory->createResponseMessage("get_peers", d.get(), remoteNode);
  211. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  212. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  213. CPPUNIT_ASSERT_EQUAL(string("token"), m->getToken());
  214. CPPUNIT_ASSERT_EQUAL((size_t)DHTBucket::K, m->getClosestKNodes().size());
  215. CPPUNIT_ASSERT(nodes[0] == m->getClosestKNodes()[0]);
  216. CPPUNIT_ASSERT(nodes[7] == m->getClosestKNodes()[7]);
  217. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  218. Util::toHex(m->getTransactionID()));
  219. } catch(Exception* e) {
  220. cerr << *e << endl;
  221. CPPUNIT_FAIL("exception thrown.");
  222. }
  223. }
  224. void DHTMessageFactoryImplTest::testCreateGetPeersReplyMessage_values()
  225. {
  226. try {
  227. SharedHandle<Dictionary> d = new Dictionary();
  228. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  229. d->put("y", new Data("r"));
  230. Dictionary* r = new Dictionary();
  231. r->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  232. Peers peers;
  233. List* values = new List();
  234. r->put("values", values);
  235. for(size_t i = 0; i < 4; ++i) {
  236. PeerHandle peer = new Peer("192.168.0."+Util::uitos(i+1), 6881+i);
  237. char buffer[6];
  238. CPPUNIT_ASSERT(PeerMessageUtil::createcompact(buffer, peer->ipaddr, peer->port));
  239. values->add(new Data(buffer, sizeof(buffer)));
  240. peers.push_back(peer);
  241. }
  242. r->put("values", values);
  243. r->put("token", new Data("token"));
  244. d->put("r", r);
  245. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  246. remoteNode->setIPAddress("192.168.0.1");
  247. remoteNode->setPort(6881);
  248. SharedHandle<DHTGetPeersReplyMessage> m = factory->createResponseMessage("get_peers", d.get(), remoteNode);
  249. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  250. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  251. CPPUNIT_ASSERT_EQUAL(string("token"), m->getToken());
  252. CPPUNIT_ASSERT_EQUAL((size_t)4, m->getValues().size());
  253. CPPUNIT_ASSERT(peers[0] == m->getValues()[0]);
  254. CPPUNIT_ASSERT(peers[3] == m->getValues()[3]);
  255. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  256. Util::toHex(m->getTransactionID()));
  257. } catch(Exception* e) {
  258. cerr << *e << endl;
  259. CPPUNIT_FAIL("exception thrown.");
  260. }
  261. }
  262. void DHTMessageFactoryImplTest::testCreateAnnouncePeerMessage()
  263. {
  264. try {
  265. SharedHandle<Dictionary> d = new Dictionary();
  266. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  267. d->put("y", new Data("q"));
  268. d->put("q", new Data("announce_peer"));
  269. Dictionary* a = new Dictionary();
  270. a->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  271. unsigned char infoHash[DHT_ID_LENGTH];
  272. memset(infoHash, 0x11, DHT_ID_LENGTH);
  273. a->put("info_hash", new Data(infoHash, DHT_ID_LENGTH));
  274. string token = "ffff";
  275. uint16_t port = 6881;
  276. a->put("port", new Data(Util::uitos(port), true));
  277. a->put("token", new Data(token));
  278. d->put("a", a);
  279. SharedHandle<DHTAnnouncePeerMessage> m = factory->createQueryMessage(d.get(), "192.168.0.1", 6882);
  280. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  281. remoteNode->setIPAddress("192.168.0.1");
  282. remoteNode->setPort(6882);
  283. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  284. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  285. CPPUNIT_ASSERT_EQUAL(token, m->getToken());
  286. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  287. Util::toHex(m->getTransactionID()));
  288. CPPUNIT_ASSERT_EQUAL(Util::toHex(infoHash, DHT_ID_LENGTH),
  289. Util::toHex(m->getInfoHash(), DHT_ID_LENGTH));
  290. CPPUNIT_ASSERT_EQUAL(port, m->getTCPPort());
  291. } catch(Exception* e) {
  292. cerr << *e << endl;
  293. string msg = e->getMsg();
  294. delete e;
  295. CPPUNIT_FAIL(msg);
  296. }
  297. }
  298. void DHTMessageFactoryImplTest::testCreateAnnouncePeerReplyMessage()
  299. {
  300. SharedHandle<Dictionary> d = new Dictionary();
  301. d->put("t", new Data(transactionID, DHT_TRANSACTION_ID_LENGTH));
  302. d->put("y", new Data("r"));
  303. Dictionary* r = new Dictionary();
  304. r->put("id", new Data(remoteNodeID, DHT_ID_LENGTH));
  305. d->put("r", r);
  306. DHTNodeHandle remoteNode = new DHTNode(remoteNodeID);
  307. remoteNode->setIPAddress("192.168.0.1");
  308. remoteNode->setPort(6881);
  309. SharedHandle<DHTAnnouncePeerReplyMessage> m = factory->createResponseMessage("announce_peer", d.get(), remoteNode);
  310. CPPUNIT_ASSERT(localNode == m->getLocalNode());
  311. CPPUNIT_ASSERT(remoteNode == m->getRemoteNode());
  312. CPPUNIT_ASSERT_EQUAL(Util::toHex(transactionID, DHT_TRANSACTION_ID_LENGTH),
  313. Util::toHex(m->getTransactionID()));
  314. }