#include "DefaultBtAnnounce.h" #include #include #include "TestUtil.h" #include "Option.h" #include "util.h" #include "Exception.h" #include "MockPieceStorage.h" #include "MockPeerStorage.h" #include "BtRuntime.h" #include "AnnounceTier.h" #include "FixedNumberRandomizer.h" #include "FileEntry.h" #include "prefs.h" #include "DownloadContext.h" #include "bittorrent_helper.h" #include "array_fun.h" namespace aria2 { class DefaultBtAnnounceTest:public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(DefaultBtAnnounceTest); CPPUNIT_TEST(testGetAnnounceUrl); CPPUNIT_TEST(testGetAnnounceUrl_withQuery); CPPUNIT_TEST(testGetAnnounceUrl_externalIP); CPPUNIT_TEST(testNoMoreAnnounce); CPPUNIT_TEST(testIsAllAnnounceFailed); CPPUNIT_TEST(testURLOrderInStoppedEvent); CPPUNIT_TEST(testURLOrderInCompletedEvent); CPPUNIT_TEST(testProcessAnnounceResponse_malformed); CPPUNIT_TEST(testProcessAnnounceResponse_failureReason); CPPUNIT_TEST(testProcessAnnounceResponse); CPPUNIT_TEST_SUITE_END(); private: SharedHandle dctx_; SharedHandle pieceStorage_; SharedHandle peerStorage_; SharedHandle btRuntime_; Option* option_; public: void setUp() { option_ = new Option(); int64_t totalLength = 4*1024*1024; int32_t pieceLength = 256*1024; static const unsigned char infoHash[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 }; std::string peerId = "-aria2-ultrafastdltl"; dctx_.reset(new DownloadContext(pieceLength, totalLength)); SharedHandle torrentAttrs(new TorrentAttribute()); torrentAttrs->infoHash = std::string(vbegin(infoHash), vend(infoHash)); dctx_->setAttribute(CTX_ATTR_BT, torrentAttrs); dctx_->getNetStat().updateDownloadLength(pieceLength*5); dctx_->getNetStat().updateUploadLength(pieceLength*6); bittorrent::setStaticPeerId(peerId); pieceStorage_.reset(new MockPieceStorage()); pieceStorage_->setTotalLength(totalLength); pieceStorage_->setCompletedLength(pieceLength*10); peerStorage_.reset(new MockPeerStorage()); btRuntime_.reset(new BtRuntime()); } void tearDown() { delete option_; } void testGetAnnounceUrl(); void testGetAnnounceUrl_withQuery(); void testGetAnnounceUrl_externalIP(); void testNoMoreAnnounce(); void testIsAllAnnounceFailed(); void testURLOrderInStoppedEvent(); void testURLOrderInCompletedEvent(); void testProcessAnnounceResponse_malformed(); void testProcessAnnounceResponse_failureReason(); void testProcessAnnounceResponse(); }; CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtAnnounceTest); namespace { template SharedHandle createAnnounceTier (InputIterator first, InputIterator last) { SharedHandle announceTier = List::g(); for(; first != last; ++first) { announceTier->append(String::g(*first)); } return announceTier; } } // namespace namespace { SharedHandle createAnnounceTier(const std::string& uri) { SharedHandle announceTier = List::g(); announceTier->append(String::g(uri)); return announceTier; } } // namespace namespace { void setAnnounceList(const SharedHandle& dctx, const SharedHandle& announceList) { std::vector > dest; for(List::ValueType::const_iterator tierIter = announceList->begin(), eoi = announceList->end(); tierIter != eoi; ++tierIter) { std::vector ntier; const List* tier = downcast(*tierIter); for(List::ValueType::const_iterator uriIter = tier->begin(), eoi2 = tier->end(); uriIter != eoi2; ++uriIter) { const String* uri = downcast(*uriIter); ntier.push_back(uri->s()); } dest.push_back(ntier); } bittorrent::getTorrentAttrs(dctx)->announceList.swap(dest); } } // namespace void DefaultBtAnnounceTest::testNoMoreAnnounce() { SharedHandle announceList = List::g(); announceList->append(createAnnounceTier("http://localhost/announce")); announceList->append(createAnnounceTier("http://backup/announce")); setAnnounceList(dctx_, announceList); DefaultBtAnnounce btAnnounce(dctx_, option_); btAnnounce.setPieceStorage(pieceStorage_); btAnnounce.setPeerStorage(peerStorage_); btAnnounce.setBtRuntime(btRuntime_); btAnnounce.setRandomizer(SharedHandle(new FixedNumberRandomizer())); btAnnounce.setTcpPort(6989); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceFailure(); CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); pieceStorage_->setAllDownloadFinished(true); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); btRuntime_->setHalt(true); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); CPPUNIT_ASSERT(btAnnounce.noMoreAnnounce()); } void DefaultBtAnnounceTest::testGetAnnounceUrl() { SharedHandle announceList = List::g(); announceList->append(createAnnounceTier("http://localhost/announce")); setAnnounceList(dctx_, announceList); DefaultBtAnnounce btAnnounce(dctx_, option_); btAnnounce.setPieceStorage(pieceStorage_); btAnnounce.setPeerStorage(peerStorage_); btAnnounce.setBtRuntime(btRuntime_); btAnnounce.setRandomizer(SharedHandle(new FixedNumberRandomizer())); btAnnounce.setTcpPort(6989); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); pieceStorage_->setAllDownloadFinished(true); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); btRuntime_->setHalt(true); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl()); } void DefaultBtAnnounceTest::testGetAnnounceUrl_withQuery() { SharedHandle announceList = List::g(); announceList->append(createAnnounceTier("http://localhost/announce?k=v")); setAnnounceList(dctx_, announceList); DefaultBtAnnounce btAnnounce(dctx_, option_); btAnnounce.setPieceStorage(pieceStorage_); btAnnounce.setPeerStorage(peerStorage_); btAnnounce.setBtRuntime(btRuntime_); btAnnounce.setRandomizer(SharedHandle(new FixedNumberRandomizer())); btAnnounce.setTcpPort(6989); CPPUNIT_ASSERT_EQUAL (std::string("http://localhost/announce?k=v&" "info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&" "peer_id=%2Daria2%2Dultrafastdltl&" "uploaded=1572864&downloaded=1310720&left=1572864&compact=1&" "key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&" "supportcrypto=1"), btAnnounce.getAnnounceUrl()); } void DefaultBtAnnounceTest::testGetAnnounceUrl_externalIP() { SharedHandle announceList = List::g(); announceList->append(createAnnounceTier("http://localhost/announce")); setAnnounceList(dctx_, announceList); option_->put(PREF_BT_EXTERNAL_IP, "192.168.1.1"); DefaultBtAnnounce btAnnounce(dctx_, option_); btAnnounce.setPieceStorage(pieceStorage_); btAnnounce.setPeerStorage(peerStorage_); btAnnounce.setBtRuntime(btRuntime_); btAnnounce.setRandomizer(SharedHandle(new FixedNumberRandomizer())); btAnnounce.setTcpPort(6989); CPPUNIT_ASSERT_EQUAL (std::string("http://localhost/announce?" "info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&" "peer_id=%2Daria2%2Dultrafastdltl&" "uploaded=1572864&downloaded=1310720&left=1572864&compact=1&" "key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&" "supportcrypto=1&ip=192.168.1.1"), btAnnounce.getAnnounceUrl()); } void DefaultBtAnnounceTest::testIsAllAnnounceFailed() { SharedHandle announceList = List::g(); announceList->append(createAnnounceTier("http://localhost/announce")); announceList->append(createAnnounceTier("http://backup/announce")); setAnnounceList(dctx_, announceList); DefaultBtAnnounce btAnnounce(dctx_, option_); btAnnounce.setPieceStorage(pieceStorage_); btAnnounce.setPeerStorage(peerStorage_); btAnnounce.setBtRuntime(btRuntime_); btAnnounce.setRandomizer(SharedHandle(new FixedNumberRandomizer())); btAnnounce.setTcpPort(6989); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceFailure(); CPPUNIT_ASSERT_EQUAL(std::string("http://backup/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceFailure(); CPPUNIT_ASSERT(!btAnnounce.isAnnounceReady()); CPPUNIT_ASSERT_EQUAL(std::string(""), btAnnounce.getAnnounceUrl()); CPPUNIT_ASSERT(btAnnounce.isAllAnnounceFailed()); btAnnounce.resetAnnounce(); CPPUNIT_ASSERT(!btAnnounce.isAllAnnounceFailed()); } void DefaultBtAnnounceTest::testURLOrderInStoppedEvent() { const char* urls[] = { "http://localhost1/announce", "http://localhost2/announce" }; SharedHandle announceList = List::g(); announceList->append(createAnnounceTier(vbegin(urls), vend(urls))); setAnnounceList(dctx_, announceList); DefaultBtAnnounce btAnnounce(dctx_, option_); btAnnounce.setPieceStorage(pieceStorage_); btAnnounce.setPeerStorage(peerStorage_); btAnnounce.setBtRuntime(btRuntime_); btAnnounce.setRandomizer(SharedHandle(new FixedNumberRandomizer())); btAnnounce.setTcpPort(6989); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); btRuntime_->setHalt(true); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceFailure(); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost2/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=0&no_peer_id=1&port=6989&event=stopped&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); } void DefaultBtAnnounceTest::testURLOrderInCompletedEvent() { const char* urls[] = { "http://localhost1/announce", "http://localhost2/announce" }; SharedHandle announceList = List::g(); announceList->append(createAnnounceTier(vbegin(urls), vend(urls))); setAnnounceList(dctx_, announceList); DefaultBtAnnounce btAnnounce(dctx_, option_); btAnnounce.setPieceStorage(pieceStorage_); btAnnounce.setPeerStorage(peerStorage_); btAnnounce.setBtRuntime(btRuntime_); btAnnounce.setRandomizer(SharedHandle(new FixedNumberRandomizer())); btAnnounce.setTcpPort(6989); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=started&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); pieceStorage_->setAllDownloadFinished(true); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost1/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceFailure(); CPPUNIT_ASSERT_EQUAL(std::string("http://localhost2/announce?info_hash=%01%23Eg%89%AB%CD%EF%01%23Eg%89%AB%CD%EF%01%23Eg&peer_id=%2Daria2%2Dultrafastdltl&uploaded=1572864&downloaded=1310720&left=1572864&compact=1&key=fastdltl&numwant=50&no_peer_id=1&port=6989&event=completed&supportcrypto=1"), btAnnounce.getAnnounceUrl()); btAnnounce.announceSuccess(); } void DefaultBtAnnounceTest::testProcessAnnounceResponse_malformed() { try { std::string res = "i123e"; DefaultBtAnnounce(dctx_, option_).processAnnounceResponse(reinterpret_cast(res.c_str()), res.size()); CPPUNIT_FAIL("exception must be thrown."); } catch(Exception& e) { std::cerr << e.stackTrace() << std::endl; } } void DefaultBtAnnounceTest::testProcessAnnounceResponse_failureReason() { try { std::string res = "d14:failure reason11:hello worlde"; DefaultBtAnnounce(dctx_, option_).processAnnounceResponse(reinterpret_cast(res.c_str()), res.size()); CPPUNIT_FAIL("exception must be thrown."); } catch(Exception& e) { std::cerr << e.stackTrace() << std::endl; } } void DefaultBtAnnounceTest::testProcessAnnounceResponse() { std::string res = "d" "15:warning message11:hello world" "10:tracker id3:foo" "8:intervali3000e" "12:min intervali1800e" "8:completei100e" "10:incompletei200e"; res += "5:peers6:"; res += fromHex("c0a800011ae1"); res += "6:peers618:"; res += fromHex("100210354527354678541237324732171ae1"); res += "e"; DefaultBtAnnounce an(dctx_, option_); an.setPeerStorage(peerStorage_); an.setBtRuntime(btRuntime_); an.processAnnounceResponse(reinterpret_cast(res.c_str()), res.size()); CPPUNIT_ASSERT_EQUAL(std::string("foo"), an.getTrackerID()); CPPUNIT_ASSERT_EQUAL((time_t)3000, an.getInterval()); CPPUNIT_ASSERT_EQUAL((time_t)1800, an.getMinInterval()); CPPUNIT_ASSERT_EQUAL(100, an.getComplete()); CPPUNIT_ASSERT_EQUAL(200, an.getIncomplete()); CPPUNIT_ASSERT_EQUAL((size_t)2, peerStorage_->getPeers().size()); SharedHandle peer = peerStorage_->getPeers()[0]; CPPUNIT_ASSERT_EQUAL(std::string("192.168.0.1"), peer->getIPAddress()); peer = peerStorage_->getPeers()[1]; CPPUNIT_ASSERT_EQUAL(std::string("1002:1035:4527:3546:7854:1237:3247:3217"), peer->getIPAddress()); } } // namespace aria2