DHTBucketTest.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. #include "DHTBucket.h"
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <cppunit/extensions/HelperMacros.h>
  5. #include "DHTNode.h"
  6. #include "Exception.h"
  7. #include "util.h"
  8. namespace aria2 {
  9. class DHTBucketTest:public CppUnit::TestFixture {
  10. CPPUNIT_TEST_SUITE(DHTBucketTest);
  11. CPPUNIT_TEST(testGetRandomNodeID);
  12. CPPUNIT_TEST(testIsInRange);
  13. CPPUNIT_TEST(testSplitAllowed);
  14. CPPUNIT_TEST(testSplit);
  15. CPPUNIT_TEST(testAddNode);
  16. CPPUNIT_TEST(testMoveToHead);
  17. CPPUNIT_TEST(testMoveToTail);
  18. CPPUNIT_TEST(testGetGoodNodes);
  19. CPPUNIT_TEST(testCacheNode);
  20. CPPUNIT_TEST(testDropNode);
  21. CPPUNIT_TEST(testGetNode);
  22. CPPUNIT_TEST_SUITE_END();
  23. public:
  24. void setUp() {}
  25. void tearDown() {}
  26. void testGetRandomNodeID();
  27. void testIsInRange();
  28. void testSplitAllowed();
  29. void testSplit();
  30. void testAddNode();
  31. void testMoveToHead();
  32. void testMoveToTail();
  33. void testGetGoodNodes();
  34. void testCacheNode();
  35. void testDropNode();
  36. void testGetNode();
  37. };
  38. CPPUNIT_TEST_SUITE_REGISTRATION(DHTBucketTest);
  39. void DHTBucketTest::testGetRandomNodeID()
  40. {
  41. unsigned char localNodeID[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
  42. 0x00, 0x00, 0x00, 0x00, 0x00,
  43. 0x00, 0x00, 0x00, 0x00, 0x00,
  44. 0x00, 0x00, 0x00, 0x00, 0x00 };
  45. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  46. {
  47. DHTBucket bucket(localNode);
  48. unsigned char nodeID[DHT_ID_LENGTH];
  49. bucket.getRandomNodeID(nodeID);
  50. }
  51. {
  52. unsigned char max[] = { 0x01, 0x01, 0xff, 0xff, 0xff,
  53. 0xff, 0xff, 0xff, 0xff, 0xff,
  54. 0xff, 0xff, 0xff, 0xff, 0xff,
  55. 0xff, 0xff, 0xff, 0xff, 0xff };
  56. unsigned char min[] = { 0x01, 0x01, 0x00, 0x00, 0x00,
  57. 0x00, 0x00, 0x00, 0x00, 0x00,
  58. 0x00, 0x00, 0x00, 0x00, 0x00,
  59. 0x00, 0x00, 0x00, 0x00, 0x00 };
  60. DHTBucket bucket(16, max, min, localNode);
  61. unsigned char nodeID[DHT_ID_LENGTH];
  62. bucket.getRandomNodeID(nodeID);
  63. CPPUNIT_ASSERT_EQUAL(std::string("0101"),
  64. util::toHex(nodeID, sizeof(nodeID)).substr(0, 4));
  65. }
  66. }
  67. void DHTBucketTest::testIsInRange()
  68. {
  69. unsigned char localNodeID[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
  70. 0x00, 0x00, 0x00, 0x00, 0x00,
  71. 0x00, 0x00, 0x00, 0x00, 0x00,
  72. 0x00, 0x00, 0x00, 0x00, 0x00 };
  73. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  74. {
  75. unsigned char nodeID[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
  76. 0x00, 0x00, 0x00, 0x00, 0x00,
  77. 0x00, 0x00, 0x00, 0x00, 0x00,
  78. 0x00, 0x00, 0x00, 0x00, 0x00 };
  79. SharedHandle<DHTNode> node(new DHTNode(nodeID));
  80. DHTBucket bucket(localNode);
  81. CPPUNIT_ASSERT(bucket.isInRange(node));
  82. memset(nodeID, 0xff, sizeof(nodeID));
  83. CPPUNIT_ASSERT(bucket.isInRange(node));
  84. }
  85. {
  86. unsigned char max[] = { 0x01, 0x01, 0xff, 0xff, 0xff,
  87. 0xff, 0xff, 0xff, 0xff, 0xff,
  88. 0xff, 0xff, 0xff, 0xff, 0xff,
  89. 0xff, 0xff, 0xff, 0xff, 0xff };
  90. unsigned char min[] = { 0x01, 0x01, 0x00, 0x00, 0x00,
  91. 0x00, 0x00, 0x00, 0x00, 0x00,
  92. 0x00, 0x00, 0x00, 0x00, 0x00,
  93. 0x00, 0x00, 0x00, 0x00, 0x00 };
  94. {
  95. //min
  96. unsigned char nodeID[] = { 0x01, 0x01, 0x00, 0x00, 0x00,
  97. 0x00, 0x00, 0x00, 0x00, 0x00,
  98. 0x00, 0x00, 0x00, 0x00, 0x00,
  99. 0x00, 0x00, 0x00, 0x00, 0x00 };
  100. SharedHandle<DHTNode> node(new DHTNode(nodeID));
  101. DHTBucket bucket(16, max, min, localNode);
  102. CPPUNIT_ASSERT(bucket.isInRange(node));
  103. }
  104. {
  105. //max
  106. unsigned char nodeID[] = { 0x01, 0x01, 0xff, 0xff, 0xff,
  107. 0xff, 0xff, 0xff, 0xff, 0xff,
  108. 0xff, 0xff, 0xff, 0xff, 0xff,
  109. 0xff, 0xff, 0xff, 0xff, 0xff };
  110. SharedHandle<DHTNode> node(new DHTNode(nodeID));
  111. DHTBucket bucket(16, max, min, localNode);
  112. CPPUNIT_ASSERT(bucket.isInRange(node));
  113. }
  114. {
  115. unsigned char nodeID[] = { 0x01, 0x01, 0x00, 0x00, 0x00,
  116. 0x00, 0x00, 0x00, 0x00, 0x00,
  117. 0xff, 0xff, 0xff, 0xff, 0xff,
  118. 0xff, 0xff, 0xff, 0xff, 0xff };
  119. SharedHandle<DHTNode> node(new DHTNode(nodeID));
  120. DHTBucket bucket(16, max, min, localNode);
  121. CPPUNIT_ASSERT(bucket.isInRange(node));
  122. }
  123. {
  124. // nodeID is out of range: smaller than this range
  125. unsigned char nodeID[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
  126. 0x00, 0x00, 0x00, 0x00, 0x00,
  127. 0x00, 0x00, 0x00, 0x00, 0x00,
  128. 0x00, 0x00, 0x00, 0x00, 0x00 };
  129. SharedHandle<DHTNode> node(new DHTNode(nodeID));
  130. DHTBucket bucket(16, max, min, localNode);
  131. CPPUNIT_ASSERT(!bucket.isInRange(node));
  132. }
  133. {
  134. // nodeID is out of range: larger than this range
  135. unsigned char nodeID[] = { 0x01, 0x02, 0xff, 0xff, 0xff,
  136. 0xff, 0xff, 0xff, 0xff, 0xff,
  137. 0xff, 0xff, 0xff, 0xff, 0xff,
  138. 0xff, 0xff, 0xff, 0xff, 0xff };
  139. SharedHandle<DHTNode> node(new DHTNode(nodeID));
  140. DHTBucket bucket(16, max, min, localNode);
  141. CPPUNIT_ASSERT(!bucket.isInRange(node));
  142. }
  143. }
  144. }
  145. void DHTBucketTest::testSplitAllowed()
  146. {
  147. {
  148. unsigned char localNodeID[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
  149. 0x00, 0x00, 0x00, 0x00, 0x00,
  150. 0x00, 0x00, 0x00, 0x00, 0x00,
  151. 0x00, 0x00, 0x00, 0x00, 0x00 };
  152. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  153. DHTBucket bucket(localNode);
  154. CPPUNIT_ASSERT(bucket.splitAllowed());
  155. }
  156. {
  157. unsigned char max[] = { 0xff, 0xff, 0xff, 0xff, 0xff,
  158. 0xff, 0xff, 0xff, 0xff, 0xff,
  159. 0xff, 0xff, 0xff, 0xff, 0xff,
  160. 0xff, 0xff, 0xff, 0xff, 0xff };
  161. unsigned char min[] = { 0xe0, 0x00, 0x00, 0x00, 0x00,
  162. 0x00, 0x00, 0x00, 0x00, 0x00,
  163. 0x00, 0x00, 0x00, 0x00, 0x00,
  164. 0x00, 0x00, 0x00, 0x00, 0x00 };
  165. {
  166. unsigned char localNodeID[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
  167. 0x00, 0x00, 0x00, 0x00, 0x00,
  168. 0x00, 0x00, 0x00, 0x00, 0x00,
  169. 0x00, 0x00, 0x00, 0x00, 0x00 };
  170. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  171. DHTBucket bucket(3, max, min, localNode);
  172. CPPUNIT_ASSERT(!bucket.splitAllowed());
  173. }
  174. {
  175. unsigned char localNodeID[] = { 0xe0, 0x00, 0x00, 0x00, 0x00,
  176. 0x00, 0x00, 0x00, 0x00, 0x00,
  177. 0x00, 0x00, 0x00, 0x00, 0x00,
  178. 0x00, 0x00, 0x00, 0x00, 0x01 };
  179. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  180. DHTBucket bucket(3, max, min, localNode);
  181. CPPUNIT_ASSERT(bucket.splitAllowed());
  182. }
  183. }
  184. }
  185. void DHTBucketTest::testSplit()
  186. {
  187. {
  188. unsigned char localNodeID[DHT_ID_LENGTH];
  189. memset(localNodeID, 0, DHT_ID_LENGTH);
  190. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  191. {
  192. DHTBucket bucket(localNode);
  193. SharedHandle<DHTBucket> r = bucket.split();
  194. {
  195. unsigned char expectedRMax[] = { 0x7f, 0xff, 0xff, 0xff, 0xff,
  196. 0xff, 0xff, 0xff, 0xff, 0xff,
  197. 0xff, 0xff, 0xff, 0xff, 0xff,
  198. 0xff, 0xff, 0xff, 0xff, 0xff };
  199. unsigned char expectedRMin[DHT_ID_LENGTH];
  200. memset(expectedRMin, 0, DHT_ID_LENGTH);
  201. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedRMax, DHT_ID_LENGTH),
  202. util::toHex(r->getMaxID(), DHT_ID_LENGTH));
  203. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedRMin, DHT_ID_LENGTH),
  204. util::toHex(r->getMinID(), DHT_ID_LENGTH));
  205. CPPUNIT_ASSERT_EQUAL((size_t)1, r->getPrefixLength());
  206. }
  207. {
  208. unsigned char expectedLMax[DHT_ID_LENGTH];
  209. memset(expectedLMax, 0xff, DHT_ID_LENGTH);
  210. unsigned char expectedLMin[] = { 0x80, 0x00, 0x00, 0x00, 0x00,
  211. 0x00, 0x00, 0x00, 0x00, 0x00,
  212. 0x00, 0x00, 0x00, 0x00, 0x00,
  213. 0x00, 0x00, 0x00, 0x00, 0x00 };
  214. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedLMax, DHT_ID_LENGTH),
  215. util::toHex(bucket.getMaxID(), DHT_ID_LENGTH));
  216. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedLMin, DHT_ID_LENGTH),
  217. util::toHex(bucket.getMinID(), DHT_ID_LENGTH));
  218. CPPUNIT_ASSERT_EQUAL((size_t)1, bucket.getPrefixLength());
  219. }
  220. }
  221. {
  222. SharedHandle<DHTBucket> bucket(new DHTBucket(localNode));
  223. for(int i = 0; i < 159; ++i) {
  224. CPPUNIT_ASSERT(bucket->splitAllowed());
  225. SharedHandle<DHTBucket> t = bucket;
  226. bucket = bucket->split();
  227. CPPUNIT_ASSERT(!t->splitAllowed());
  228. }
  229. CPPUNIT_ASSERT(!bucket->splitAllowed());
  230. unsigned char expectedMax[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
  231. 0x00, 0x00, 0x00, 0x00, 0x00,
  232. 0x00, 0x00, 0x00, 0x00, 0x00,
  233. 0x00, 0x00, 0x00, 0x00, 0x01 };
  234. unsigned char expectedMin[DHT_ID_LENGTH];
  235. memset(expectedMin, 0, DHT_ID_LENGTH);
  236. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedMax, DHT_ID_LENGTH),
  237. util::toHex(bucket->getMaxID(), DHT_ID_LENGTH));
  238. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedMin, DHT_ID_LENGTH),
  239. util::toHex(bucket->getMinID(), DHT_ID_LENGTH));
  240. CPPUNIT_ASSERT_EQUAL((size_t)159, bucket->getPrefixLength());
  241. }
  242. }
  243. {
  244. unsigned char localNodeID[DHT_ID_LENGTH];
  245. memset(localNodeID, 0, DHT_ID_LENGTH);
  246. localNodeID[0] = 0x80;
  247. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  248. DHTBucket bucket(localNode);
  249. SharedHandle<DHTBucket> r = bucket.split();
  250. {
  251. unsigned char expectedRMax[] = { 0x7f, 0xff, 0xff, 0xff, 0xff,
  252. 0xff, 0xff, 0xff, 0xff, 0xff,
  253. 0xff, 0xff, 0xff, 0xff, 0xff,
  254. 0xff, 0xff, 0xff, 0xff, 0xff };
  255. unsigned char expectedRMin[DHT_ID_LENGTH];
  256. memset(expectedRMin, 0, DHT_ID_LENGTH);
  257. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedRMax, DHT_ID_LENGTH),
  258. util::toHex(r->getMaxID(), DHT_ID_LENGTH));
  259. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedRMin, DHT_ID_LENGTH),
  260. util::toHex(r->getMinID(), DHT_ID_LENGTH));
  261. CPPUNIT_ASSERT_EQUAL((size_t)1, r->getPrefixLength());
  262. }
  263. {
  264. unsigned char expectedLMax[DHT_ID_LENGTH];
  265. memset(expectedLMax, 0xff, DHT_ID_LENGTH);
  266. unsigned char expectedLMin[] = { 0x80, 0x00, 0x00, 0x00, 0x00,
  267. 0x00, 0x00, 0x00, 0x00, 0x00,
  268. 0x00, 0x00, 0x00, 0x00, 0x00,
  269. 0x00, 0x00, 0x00, 0x00, 0x00 };
  270. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedLMax, DHT_ID_LENGTH),
  271. util::toHex(bucket.getMaxID(), DHT_ID_LENGTH));
  272. CPPUNIT_ASSERT_EQUAL(util::toHex(expectedLMin, DHT_ID_LENGTH),
  273. util::toHex(bucket.getMinID(), DHT_ID_LENGTH));
  274. CPPUNIT_ASSERT_EQUAL((size_t)1, bucket.getPrefixLength());
  275. }
  276. }
  277. }
  278. namespace {
  279. void createID(unsigned char* id, unsigned char firstChar, unsigned char lastChar)
  280. {
  281. memset(id, 0, DHT_ID_LENGTH);
  282. id[0] = firstChar;
  283. id[DHT_ID_LENGTH-1] = lastChar;
  284. }
  285. } // namespace
  286. void DHTBucketTest::testAddNode()
  287. {
  288. unsigned char localNodeID[DHT_ID_LENGTH];
  289. memset(localNodeID, 0, DHT_ID_LENGTH);
  290. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  291. DHTBucket bucket(localNode);
  292. unsigned char id[DHT_ID_LENGTH];
  293. SharedHandle<DHTNode> nodes[8];
  294. for(size_t i = 0; i < DHTBucket::K; ++i) {
  295. createID(id, 0xf0, i);
  296. nodes[i].reset(new DHTNode(id));
  297. CPPUNIT_ASSERT(bucket.addNode(nodes[i]));
  298. }
  299. createID(id, 0xf0, 0xff);
  300. SharedHandle<DHTNode> newNode(new DHTNode(id));
  301. CPPUNIT_ASSERT(!bucket.addNode(newNode));
  302. // nodes[0] is located at the tail of the bucket(least recent seen)
  303. nodes[0]->markBad();
  304. CPPUNIT_ASSERT(bucket.addNode(newNode));
  305. CPPUNIT_ASSERT(*bucket.getNodes().back() == *newNode);
  306. }
  307. void DHTBucketTest::testMoveToHead()
  308. {
  309. unsigned char localNodeID[DHT_ID_LENGTH];
  310. memset(localNodeID, 0, DHT_ID_LENGTH);
  311. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  312. DHTBucket bucket(localNode);
  313. unsigned char id[DHT_ID_LENGTH];
  314. SharedHandle<DHTNode> nodes[8];
  315. for(size_t i = 0; i < DHTBucket::K; ++i) {
  316. createID(id, 0xf0, i);
  317. nodes[i].reset(new DHTNode(id));
  318. CPPUNIT_ASSERT(bucket.addNode(nodes[i]));
  319. }
  320. bucket.moveToHead(nodes[DHTBucket::K-1]);
  321. CPPUNIT_ASSERT(*bucket.getNodes().front() == *nodes[DHTBucket::K-1]);
  322. }
  323. void DHTBucketTest::testMoveToTail()
  324. {
  325. unsigned char localNodeID[DHT_ID_LENGTH];
  326. memset(localNodeID, 0, DHT_ID_LENGTH);
  327. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  328. DHTBucket bucket(localNode);
  329. unsigned char id[DHT_ID_LENGTH];
  330. SharedHandle<DHTNode> nodes[8];
  331. for(size_t i = 0; i < DHTBucket::K; ++i) {
  332. createID(id, 0xf0, i);
  333. nodes[i].reset(new DHTNode(id));
  334. CPPUNIT_ASSERT(bucket.addNode(nodes[i]));
  335. }
  336. bucket.moveToTail(nodes[0]);
  337. CPPUNIT_ASSERT(*bucket.getNodes().back() == *nodes[0]);
  338. }
  339. void DHTBucketTest::testGetGoodNodes()
  340. {
  341. unsigned char localNodeID[DHT_ID_LENGTH];
  342. memset(localNodeID, 0, DHT_ID_LENGTH);
  343. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  344. DHTBucket bucket(localNode);
  345. unsigned char id[DHT_ID_LENGTH];
  346. SharedHandle<DHTNode> nodes[8];
  347. for(size_t i = 0; i < DHTBucket::K; ++i) {
  348. createID(id, 0xf0, i);
  349. nodes[i].reset(new DHTNode(id));
  350. nodes[i]->setPort(6881+i);
  351. CPPUNIT_ASSERT(bucket.addNode(nodes[i]));
  352. }
  353. nodes[3]->markBad();
  354. nodes[5]->markBad();
  355. std::vector<SharedHandle<DHTNode> > goodNodes;
  356. bucket.getGoodNodes(goodNodes);
  357. CPPUNIT_ASSERT_EQUAL((size_t)6, goodNodes.size());
  358. CPPUNIT_ASSERT_EQUAL((uint16_t)6881, goodNodes[0]->getPort());
  359. CPPUNIT_ASSERT_EQUAL((uint16_t)6882, goodNodes[1]->getPort());
  360. CPPUNIT_ASSERT_EQUAL((uint16_t)6883, goodNodes[2]->getPort());
  361. CPPUNIT_ASSERT_EQUAL((uint16_t)6885, goodNodes[3]->getPort());
  362. CPPUNIT_ASSERT_EQUAL((uint16_t)6887, goodNodes[4]->getPort());
  363. CPPUNIT_ASSERT_EQUAL((uint16_t)6888, goodNodes[5]->getPort());
  364. }
  365. void DHTBucketTest::testCacheNode()
  366. {
  367. unsigned char localNodeID[DHT_ID_LENGTH];
  368. memset(localNodeID, 0, DHT_ID_LENGTH);
  369. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  370. DHTBucket bucket(localNode);
  371. SharedHandle<DHTNode> n1(new DHTNode());
  372. SharedHandle<DHTNode> n2(new DHTNode());
  373. SharedHandle<DHTNode> n3(new DHTNode());
  374. bucket.cacheNode(n1);
  375. bucket.cacheNode(n2);
  376. CPPUNIT_ASSERT_EQUAL((size_t)2, bucket.getCachedNodes().size());
  377. CPPUNIT_ASSERT(*n2 == *bucket.getCachedNodes()[0]);
  378. bucket.cacheNode(n3);
  379. CPPUNIT_ASSERT_EQUAL((size_t)2, bucket.getCachedNodes().size());
  380. CPPUNIT_ASSERT(*n3 == *bucket.getCachedNodes()[0]);
  381. CPPUNIT_ASSERT(*n2 == *bucket.getCachedNodes()[1]);
  382. }
  383. void DHTBucketTest::testDropNode()
  384. {
  385. unsigned char localNodeID[DHT_ID_LENGTH];
  386. memset(localNodeID, 0, DHT_ID_LENGTH);
  387. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  388. DHTBucket bucket(localNode);
  389. unsigned char id[DHT_ID_LENGTH];
  390. SharedHandle<DHTNode> nodes[8];
  391. for(size_t i = 0; i < DHTBucket::K; ++i) {
  392. createID(id, 0xf0, i);
  393. nodes[i].reset(new DHTNode(id));
  394. nodes[i]->setPort(6881+i);
  395. CPPUNIT_ASSERT(bucket.addNode(nodes[i]));
  396. }
  397. SharedHandle<DHTNode> cachedNode1(new DHTNode());
  398. SharedHandle<DHTNode> cachedNode2(new DHTNode());
  399. bucket.dropNode(nodes[3]);
  400. // nothing happens because the replacement cache is empty.
  401. {
  402. std::deque<SharedHandle<DHTNode> > tnodes = bucket.getNodes();
  403. CPPUNIT_ASSERT_EQUAL((size_t)8, tnodes.size());
  404. CPPUNIT_ASSERT(*nodes[3] == *tnodes[3]);
  405. }
  406. bucket.cacheNode(cachedNode1);
  407. bucket.cacheNode(cachedNode2);
  408. bucket.dropNode(nodes[3]);
  409. {
  410. std::deque<SharedHandle<DHTNode> > tnodes = bucket.getNodes();
  411. CPPUNIT_ASSERT_EQUAL((size_t)8, tnodes.size());
  412. CPPUNIT_ASSERT(tnodes.end() ==
  413. std::find_if(tnodes.begin(), tnodes.end(),
  414. derefEqual(nodes[3])));
  415. CPPUNIT_ASSERT(*cachedNode2 == *tnodes[7]);
  416. }
  417. CPPUNIT_ASSERT_EQUAL((size_t)1, bucket.getCachedNodes().size());
  418. CPPUNIT_ASSERT(*cachedNode1 == *bucket.getCachedNodes()[0]);
  419. }
  420. void DHTBucketTest::testGetNode()
  421. {
  422. unsigned char localNodeID[DHT_ID_LENGTH];
  423. memset(localNodeID, 0, DHT_ID_LENGTH);
  424. SharedHandle<DHTNode> localNode(new DHTNode(localNodeID));
  425. DHTBucket bucket(localNode);
  426. unsigned char id[DHT_ID_LENGTH];
  427. createID(id, 0xf0, 0);
  428. SharedHandle<DHTNode> node(new DHTNode(id));
  429. node->setIPAddress("192.168.0.1");
  430. node->setPort(6881);
  431. CPPUNIT_ASSERT(bucket.addNode(node));
  432. CPPUNIT_ASSERT(bucket.getNode(id, "192.168.0.1", 6881));
  433. CPPUNIT_ASSERT(!bucket.getNode(id, "192.168.0.2", 6881));
  434. CPPUNIT_ASSERT(!bucket.getNode(id, "192.168.0.1", 6882));
  435. CPPUNIT_ASSERT(!bucket.getNode(localNodeID, "192.168.0.1", 6881));
  436. }
  437. } // namespace aria2