DefaultBtMessageDispatcherTest.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. #include "DefaultBtMessageDispatcher.h"
  2. #include "Util.h"
  3. #include "Exception.h"
  4. #include "MockPieceStorage.h"
  5. #include "MockPeerStorage.h"
  6. #include "BtRegistry.h"
  7. #include "DefaultBtContext.h"
  8. #include "MockBtMessage.h"
  9. #include "MockBtMessageFactory.h"
  10. #include "prefs.h"
  11. #include "BtCancelSendingPieceEvent.h"
  12. #include <cppunit/extensions/HelperMacros.h>
  13. using namespace std;
  14. class DefaultBtMessageDispatcherTest:public CppUnit::TestFixture {
  15. CPPUNIT_TEST_SUITE(DefaultBtMessageDispatcherTest);
  16. CPPUNIT_TEST(testAddMessage);
  17. CPPUNIT_TEST(testSendMessages);
  18. CPPUNIT_TEST(testSendMessages_underUploadLimit);
  19. CPPUNIT_TEST(testSendMessages_overUploadLimit);
  20. CPPUNIT_TEST(testSendMessages_sendingInProgress);
  21. CPPUNIT_TEST(testDoCancelSendingPieceAction);
  22. CPPUNIT_TEST(testCheckRequestSlotAndDoNecessaryThing);
  23. CPPUNIT_TEST(testCheckRequestSlotAndDoNecessaryThing_timeout);
  24. CPPUNIT_TEST(testCheckRequestSlotAndDoNecessaryThing_completeBlock);
  25. CPPUNIT_TEST(testIsSendingInProgress);
  26. CPPUNIT_TEST(testCountOutstandingRequest);
  27. CPPUNIT_TEST(testIsOutstandingRequest);
  28. CPPUNIT_TEST(testGetOutstandingRequest);
  29. CPPUNIT_TEST(testRemoveOutstandingRequest);
  30. CPPUNIT_TEST_SUITE_END();
  31. private:
  32. BtContextHandle btContext;
  33. Option* option;
  34. PeerHandle peer;
  35. DefaultBtMessageDispatcherHandle btMessageDispatcher;
  36. MockPeerStorageHandle peerStorage;
  37. MockPieceStorageHandle pieceStorage;
  38. public:
  39. DefaultBtMessageDispatcherTest():btContext(0), peer(0), btMessageDispatcher(0) {}
  40. void tearDown() {
  41. delete option;
  42. }
  43. void testAddMessage();
  44. void testSendMessages();
  45. void testSendMessages_underUploadLimit();
  46. void testSendMessages_overUploadLimit();
  47. void testSendMessages_sendingInProgress();
  48. void testDoCancelSendingPieceAction();
  49. void testCheckRequestSlotAndDoNecessaryThing();
  50. void testCheckRequestSlotAndDoNecessaryThing_timeout();
  51. void testCheckRequestSlotAndDoNecessaryThing_completeBlock();
  52. void testIsSendingInProgress();
  53. void testCountOutstandingRequest();
  54. void testIsOutstandingRequest();
  55. void testGetOutstandingRequest();
  56. void testRemoveOutstandingRequest();
  57. class MockBtMessage2 : public MockBtMessage {
  58. private:
  59. bool onQueuedCalled;
  60. bool sendCalled;
  61. bool doCancelActionCalled;
  62. public:
  63. string type;
  64. public:
  65. MockBtMessage2():onQueuedCalled(false),
  66. sendCalled(false),
  67. doCancelActionCalled(false)
  68. {}
  69. virtual ~MockBtMessage2() {}
  70. virtual void onQueued() {
  71. onQueuedCalled = true;
  72. }
  73. bool isOnQueuedCalled() const {
  74. return onQueuedCalled;
  75. }
  76. virtual void send() {
  77. sendCalled = true;
  78. }
  79. bool isSendCalled() const {
  80. return sendCalled;
  81. }
  82. virtual void handleEvent(const BtEventHandle& event) {
  83. BtCancelSendingPieceEvent* e =
  84. dynamic_cast<BtCancelSendingPieceEvent*>(event.get());
  85. if(e) {
  86. doCancelActionCalled = true;
  87. }
  88. }
  89. bool isDoCancelActionCalled() const {
  90. return doCancelActionCalled;
  91. }
  92. };
  93. typedef SharedHandle<MockBtMessage2> MockBtMessage2Handle;
  94. class MockPieceStorage2 : public MockPieceStorage {
  95. private:
  96. PieceHandle piece;
  97. public:
  98. virtual PieceHandle getPiece(int index) {
  99. return piece;
  100. }
  101. void setPiece(const PieceHandle& piece) {
  102. this->piece = piece;
  103. }
  104. };
  105. class MockBtMessageFactory2 : public MockBtMessageFactory {
  106. public:
  107. virtual BtMessageHandle
  108. createCancelMessage(int32_t index, int32_t begin, uint32_t length) {
  109. MockBtMessage2Handle btMsg = new MockBtMessage2();
  110. btMsg->type = "cancel";
  111. return btMsg;
  112. }
  113. };
  114. void setUp() {
  115. btContext = new DefaultBtContext();
  116. btContext->load("test.torrent");
  117. option = new Option();
  118. peer = new Peer("192.168.0.1", 6969,
  119. btContext->getPieceLength(),
  120. btContext->getTotalLength());
  121. peerStorage = new MockPeerStorage();
  122. pieceStorage = new MockPieceStorage();
  123. BtRegistry::clear();
  124. BtRegistry::registerPeerStorage(btContext->getInfoHashAsString(),
  125. peerStorage);
  126. BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(),
  127. pieceStorage);
  128. BtRegistry::registerPeerObjectCluster(btContext->getInfoHashAsString(),
  129. new PeerObjectCluster());
  130. PeerObjectHandle peerObject = new PeerObject();
  131. peerObject->btMessageFactory = new MockBtMessageFactory2();
  132. PEER_OBJECT_CLUSTER(btContext)->registerHandle(peer->getId(), peerObject);
  133. btMessageDispatcher = new DefaultBtMessageDispatcher();
  134. btMessageDispatcher->setCuid(1);
  135. btMessageDispatcher->setBtContext(btContext);
  136. btMessageDispatcher->setPeer(peer);
  137. btMessageDispatcher->setOption(option);
  138. }
  139. };
  140. CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtMessageDispatcherTest);
  141. void DefaultBtMessageDispatcherTest::testAddMessage() {
  142. MockBtMessage2Handle msg = new MockBtMessage2();
  143. CPPUNIT_ASSERT_EQUAL(false, msg->isOnQueuedCalled());
  144. btMessageDispatcher->addMessageToQueue(msg);
  145. CPPUNIT_ASSERT_EQUAL(true, msg->isOnQueuedCalled());
  146. CPPUNIT_ASSERT_EQUAL((size_t)1,
  147. btMessageDispatcher->getMessageQueue().size());
  148. }
  149. void DefaultBtMessageDispatcherTest::testSendMessages() {
  150. option->put(PREF_MAX_UPLOAD_LIMIT, "0");
  151. TransferStat stat;
  152. stat.setUploadSpeed(0);
  153. peerStorage->setStat(stat);
  154. MockBtMessage2Handle msg1 = new MockBtMessage2();
  155. msg1->setSendingInProgress(false);
  156. msg1->setUploading(false);
  157. MockBtMessage2Handle msg2 = new MockBtMessage2();
  158. msg2->setSendingInProgress(false);
  159. msg2->setUploading(false);
  160. btMessageDispatcher->addMessageToQueue(msg1);
  161. btMessageDispatcher->addMessageToQueue(msg2);
  162. btMessageDispatcher->sendMessages();
  163. CPPUNIT_ASSERT(msg1->isSendCalled());
  164. CPPUNIT_ASSERT(msg2->isSendCalled());
  165. }
  166. void DefaultBtMessageDispatcherTest::testSendMessages_underUploadLimit() {
  167. option->put(PREF_MAX_UPLOAD_LIMIT, "0");
  168. TransferStat stat;
  169. stat.setUploadSpeed(0);
  170. peerStorage->setStat(stat);
  171. MockBtMessage2Handle msg1 = new MockBtMessage2();
  172. msg1->setSendingInProgress(false);
  173. msg1->setUploading(true);
  174. MockBtMessage2Handle msg2 = new MockBtMessage2();
  175. msg2->setSendingInProgress(false);
  176. msg2->setUploading(true);
  177. btMessageDispatcher->addMessageToQueue(msg1);
  178. btMessageDispatcher->addMessageToQueue(msg2);
  179. btMessageDispatcher->sendMessages();
  180. CPPUNIT_ASSERT(msg1->isSendCalled());
  181. CPPUNIT_ASSERT(msg2->isSendCalled());
  182. }
  183. void DefaultBtMessageDispatcherTest::testSendMessages_overUploadLimit() {
  184. option->put(PREF_MAX_UPLOAD_LIMIT, "100");
  185. TransferStat stat;
  186. stat.setUploadSpeed(150);
  187. peerStorage->setStat(stat);
  188. MockBtMessage2Handle msg1 = new MockBtMessage2();
  189. msg1->setSendingInProgress(false);
  190. msg1->setUploading(true);
  191. MockBtMessage2Handle msg2 = new MockBtMessage2();
  192. msg2->setSendingInProgress(false);
  193. msg2->setUploading(true);
  194. MockBtMessage2Handle msg3 = new MockBtMessage2();
  195. msg3->setSendingInProgress(false);
  196. msg3->setUploading(false);
  197. btMessageDispatcher->addMessageToQueue(msg1);
  198. btMessageDispatcher->addMessageToQueue(msg2);
  199. btMessageDispatcher->addMessageToQueue(msg3);
  200. btMessageDispatcher->sendMessages();
  201. CPPUNIT_ASSERT(!msg1->isSendCalled());
  202. CPPUNIT_ASSERT(!msg2->isSendCalled());
  203. CPPUNIT_ASSERT(msg3->isSendCalled());
  204. CPPUNIT_ASSERT_EQUAL((size_t)2, btMessageDispatcher->getMessageQueue().size());
  205. }
  206. void DefaultBtMessageDispatcherTest::testSendMessages_sendingInProgress() {
  207. MockBtMessage2Handle msg1 = new MockBtMessage2();
  208. msg1->setSendingInProgress(false);
  209. msg1->setUploading(false);
  210. MockBtMessage2Handle msg2 = new MockBtMessage2();
  211. msg2->setSendingInProgress(true);
  212. msg2->setUploading(false);
  213. MockBtMessage2Handle msg3 = new MockBtMessage2();
  214. msg3->setSendingInProgress(false);
  215. msg3->setUploading(false);
  216. btMessageDispatcher->addMessageToQueue(msg1);
  217. btMessageDispatcher->addMessageToQueue(msg2);
  218. btMessageDispatcher->addMessageToQueue(msg3);
  219. btMessageDispatcher->sendMessages();
  220. CPPUNIT_ASSERT(msg1->isSendCalled());
  221. CPPUNIT_ASSERT(msg2->isSendCalled());
  222. CPPUNIT_ASSERT(!msg3->isSendCalled());
  223. CPPUNIT_ASSERT_EQUAL((size_t)2, btMessageDispatcher->getMessageQueue().size());
  224. }
  225. void DefaultBtMessageDispatcherTest::testDoCancelSendingPieceAction() {
  226. MockBtMessage2Handle msg1 = new MockBtMessage2();
  227. MockBtMessage2Handle msg2 = new MockBtMessage2();
  228. btMessageDispatcher->addMessageToQueue(msg1);
  229. btMessageDispatcher->addMessageToQueue(msg2);
  230. btMessageDispatcher->doCancelSendingPieceAction(0, 0, 0);
  231. CPPUNIT_ASSERT_EQUAL(true, msg1->isDoCancelActionCalled());
  232. CPPUNIT_ASSERT_EQUAL(true, msg2->isDoCancelActionCalled());
  233. }
  234. int MY_PIECE_LENGTH = 16*1024;
  235. void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing() {
  236. RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
  237. PieceHandle piece = new Piece(0, MY_PIECE_LENGTH);
  238. assert(piece->getMissingUnusedBlockIndex() == 0);
  239. SharedHandle<MockPieceStorage2> pieceStorage = new MockPieceStorage2();
  240. pieceStorage->setPiece(piece);
  241. CPPUNIT_ASSERT(BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(),
  242. pieceStorage));
  243. option->put(PREF_BT_REQUEST_TIMEOUT, "60");
  244. btMessageDispatcher = new DefaultBtMessageDispatcher();
  245. btMessageDispatcher->setCuid(1);
  246. btMessageDispatcher->setBtContext(btContext);
  247. btMessageDispatcher->setPeer(peer);
  248. btMessageDispatcher->setOption(option);
  249. btMessageDispatcher->addOutstandingRequest(slot);
  250. btMessageDispatcher->checkRequestSlotAndDoNecessaryThing();
  251. CPPUNIT_ASSERT_EQUAL((size_t)0, btMessageDispatcher->getMessageQueue().size());
  252. CPPUNIT_ASSERT_EQUAL((size_t)1, btMessageDispatcher->getRequestSlots().size());
  253. }
  254. void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_timeout() {
  255. RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
  256. // make this slot timeout
  257. slot.setDispatchedTime(0);
  258. PieceHandle piece = new Piece(0, MY_PIECE_LENGTH);
  259. assert(piece->getMissingUnusedBlockIndex() == 0);
  260. SharedHandle<MockPieceStorage2> pieceStorage = new MockPieceStorage2();
  261. pieceStorage->setPiece(piece);
  262. CPPUNIT_ASSERT(BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(),
  263. pieceStorage));
  264. option->put(PREF_BT_REQUEST_TIMEOUT, "60");
  265. btMessageDispatcher = new DefaultBtMessageDispatcher();
  266. btMessageDispatcher->setCuid(1);
  267. btMessageDispatcher->setBtContext(btContext);
  268. btMessageDispatcher->setPeer(peer);
  269. btMessageDispatcher->setOption(option);
  270. btMessageDispatcher->addOutstandingRequest(slot);
  271. btMessageDispatcher->checkRequestSlotAndDoNecessaryThing();
  272. CPPUNIT_ASSERT_EQUAL((size_t)0, btMessageDispatcher->getMessageQueue().size());
  273. CPPUNIT_ASSERT_EQUAL((size_t)0, btMessageDispatcher->getRequestSlots().size());
  274. CPPUNIT_ASSERT_EQUAL(false, piece->isBlockUsed(0));
  275. CPPUNIT_ASSERT_EQUAL(true, peer->snubbing);
  276. }
  277. void DefaultBtMessageDispatcherTest::testCheckRequestSlotAndDoNecessaryThing_completeBlock() {
  278. RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
  279. PieceHandle piece = new Piece(0, MY_PIECE_LENGTH);
  280. piece->completeBlock(0);
  281. SharedHandle<MockPieceStorage2> pieceStorage = new MockPieceStorage2();
  282. pieceStorage->setPiece(piece);
  283. CPPUNIT_ASSERT(BtRegistry::registerPieceStorage(btContext->getInfoHashAsString(),
  284. pieceStorage));
  285. option->put(PREF_BT_REQUEST_TIMEOUT, "60");
  286. btMessageDispatcher = new DefaultBtMessageDispatcher();
  287. btMessageDispatcher->setCuid(1);
  288. btMessageDispatcher->setBtContext(btContext);
  289. btMessageDispatcher->setPeer(peer);
  290. btMessageDispatcher->setOption(option);
  291. btMessageDispatcher->addOutstandingRequest(slot);
  292. btMessageDispatcher->checkRequestSlotAndDoNecessaryThing();
  293. CPPUNIT_ASSERT_EQUAL((size_t)1, btMessageDispatcher->getMessageQueue().size());
  294. CPPUNIT_ASSERT_EQUAL((size_t)0, btMessageDispatcher->getRequestSlots().size());
  295. }
  296. void DefaultBtMessageDispatcherTest::testIsSendingInProgress() {
  297. CPPUNIT_ASSERT(!btMessageDispatcher->isSendingInProgress());
  298. MockBtMessage2Handle msg = new MockBtMessage2();
  299. msg->setSendingInProgress(false);
  300. btMessageDispatcher->addMessageToQueue(msg);
  301. CPPUNIT_ASSERT(!btMessageDispatcher->isSendingInProgress());
  302. msg->setSendingInProgress(true);
  303. CPPUNIT_ASSERT(btMessageDispatcher->isSendingInProgress());
  304. }
  305. void DefaultBtMessageDispatcherTest::testCountOutstandingRequest() {
  306. RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
  307. btMessageDispatcher->addOutstandingRequest(slot);
  308. CPPUNIT_ASSERT_EQUAL((uint32_t)1, btMessageDispatcher->countOutstandingRequest());
  309. }
  310. void DefaultBtMessageDispatcherTest::testIsOutstandingRequest() {
  311. RequestSlot slot(0, 0, MY_PIECE_LENGTH, 0);
  312. btMessageDispatcher->addOutstandingRequest(slot);
  313. CPPUNIT_ASSERT(btMessageDispatcher->isOutstandingRequest(0, 0));
  314. CPPUNIT_ASSERT(!btMessageDispatcher->isOutstandingRequest(0, 1));
  315. CPPUNIT_ASSERT(!btMessageDispatcher->isOutstandingRequest(1, 0));
  316. CPPUNIT_ASSERT(!btMessageDispatcher->isOutstandingRequest(1, 1));
  317. }
  318. void DefaultBtMessageDispatcherTest::testGetOutstandingRequest() {
  319. RequestSlot slot(1, 1024, 16*1024, 10);
  320. btMessageDispatcher->addOutstandingRequest(slot);
  321. RequestSlot s2 = btMessageDispatcher->getOutstandingRequest(1, 1024, 16*1024);
  322. CPPUNIT_ASSERT(!RequestSlot::isNull(s2));
  323. RequestSlot s3 = btMessageDispatcher->getOutstandingRequest(1, 1024, 17*1024);
  324. CPPUNIT_ASSERT(RequestSlot::isNull(s3));
  325. RequestSlot s4 = btMessageDispatcher->getOutstandingRequest(1, 2*1024, 16*1024);
  326. CPPUNIT_ASSERT(RequestSlot::isNull(s4));
  327. RequestSlot s5 = btMessageDispatcher->getOutstandingRequest(2, 1024, 16*1024);
  328. CPPUNIT_ASSERT(RequestSlot::isNull(s5));
  329. }
  330. void DefaultBtMessageDispatcherTest::testRemoveOutstandingRequest() {
  331. RequestSlot slot(1, 1024, 16*1024, 10);
  332. btMessageDispatcher->addOutstandingRequest(slot);
  333. RequestSlot s2 = btMessageDispatcher->getOutstandingRequest(1, 1024, 16*1024);
  334. CPPUNIT_ASSERT(!RequestSlot::isNull(s2));
  335. btMessageDispatcher->removeOutstandingRequest(s2);
  336. RequestSlot s3 = btMessageDispatcher->getOutstandingRequest(1, 1024, 16*1024);
  337. CPPUNIT_ASSERT(RequestSlot::isNull(s3));
  338. }