2007-11-04 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Fixed: the listen port sent to the tracker is wrong. If aria2 
fails
	to open listen port, then remove the port number from the 
tracker
	request.
	* src/DefaultBtAnnounce.cc 
	* test/DefaultBtAnnounceTest.cc
	* test/MockPieceStorage.h
	
	Inject randomizer to DefaultBtAnnounce and DefaultBtContext to 
make
	them more testable.
	* src/DefaultBtAnnounce.{h, cc}
	* src/DefaultBtContext.{h, cc}
	* src/Util.{h, cc}
	* test/DefaultBtAnnounceTest.cc
	* test/DefaultBtContextTest.cc
	* test/UtilTest.cc
	
	Added 'B' to upload bytes readout.
	* src/ConsoleStatCalc.cc

	Now the listen port for BitTorrent download is opened when it is
	needed.
	* src/DownloadEngineFactory.cc
	* src/BtSetup.{h, cc}
	* src/PeerListenCommand.{h, cc}
	
	Now an exception thrown while parsing tracker response is now 
logged.
	If DlAbortEx is catched, then btAnnounce->resetAnnounce() 
immediately
	called, which means no retry is made in this case, assuming a 
tracker
	has a problem.
	* src/TrackerWatcherCommand.cc
	
	Fixed: downloading a file whose length is unkown fails.
	* src/DownloadCommand.cc

	Simplified prepareForNextSegment()
	* src/DownloadCommand.cc

	Updated
	* po/POTFILES.in
pull/1/head
Tatsuhiro Tsujikawa 2007-11-04 12:26:12 +00:00
parent 166f7aa8c2
commit d8ae699182
22 changed files with 343 additions and 76 deletions

View File

@ -1,3 +1,45 @@
2007-11-04 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Fixed: the listen port sent to the tracker is wrong. If aria2 fails
to open listen port, then remove the port number from the tracker
request.
* src/DefaultBtAnnounce.cc
* test/DefaultBtAnnounceTest.cc
* test/MockPieceStorage.h
Inject randomizer to DefaultBtAnnounce and DefaultBtContext to make
them more testable.
* src/DefaultBtAnnounce.{h, cc}
* src/DefaultBtContext.{h, cc}
* src/Util.{h, cc}
* test/DefaultBtAnnounceTest.cc
* test/DefaultBtContextTest.cc
* test/UtilTest.cc
Added 'B' to upload bytes readout.
* src/ConsoleStatCalc.cc
Now the listen port for BitTorrent download is opened when it is
needed.
* src/DownloadEngineFactory.cc
* src/BtSetup.{h, cc}
* src/PeerListenCommand.{h, cc}
Now an exception thrown while parsing tracker response is now logged.
If DlAbortEx is catched, then btAnnounce->resetAnnounce() immediately
called, which means no retry is made in this case, assuming a tracker
has a problem.
* src/TrackerWatcherCommand.cc
Fixed: downloading a file whose length is unkown fails.
* src/DownloadCommand.cc
Simplified prepareForNextSegment()
* src/DownloadCommand.cc
Updated
* po/POTFILES.in
2007-11-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2007-11-03 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Re-implemented a file listing for Metalink, which was dropped while Re-implemented a file listing for Metalink, which was dropped while

3
TODO
View File

@ -51,9 +51,6 @@
-- remaining features to be implemented for 0.12.0 release -- remaining features to be implemented for 0.12.0 release
* Reimplement ChecksumCommand(validation using 1 checksum for 1 file) * Reimplement ChecksumCommand(validation using 1 checksum for 1 file)
* Implement duplicate download checking in Bt * Implement duplicate download checking in Bt
* Add PeerListenCommand to DownloadEngine only when it is really necessary.
* improve --metalink-location field * improve --metalink-location field
* Use content-type for PostDownloadHandler * Use content-type for PostDownloadHandler
* Torrent information
* Fix SleepCommand to catch halt signal * Fix SleepCommand to catch halt signal

View File

@ -5,4 +5,5 @@
../src/MultiUrlRequestInfo.cc \ ../src/MultiUrlRequestInfo.cc \
../src/RequestGroupMan.cc \ ../src/RequestGroupMan.cc \
../src/Util.cc \ ../src/Util.cc \
../src/version_usage.cc ../src/version_usage.cc \
../src/BtSetup.cc

View File

@ -6,3 +6,4 @@ src/MultiUrlRequestInfo.cc
src/RequestGroupMan.cc src/RequestGroupMan.cc
src/Util.cc src/Util.cc
src/version_usage.cc src/version_usage.cc
src/BtSetup.cc

View File

@ -42,6 +42,7 @@
#include "SeedCheckCommand.h" #include "SeedCheckCommand.h"
#include "PeerChokeCommand.h" #include "PeerChokeCommand.h"
#include "ActivePeerConnectionCommand.h" #include "ActivePeerConnectionCommand.h"
#include "PeerListenCommand.h"
#include "UnionSeedCriteria.h" #include "UnionSeedCriteria.h"
#include "TimeSeedCriteria.h" #include "TimeSeedCriteria.h"
#include "ShareRatioSeedCriteria.h" #include "ShareRatioSeedCriteria.h"
@ -49,6 +50,11 @@
#include "DefaultBtProgressInfoFile.h" #include "DefaultBtProgressInfoFile.h"
#include "CUIDCounter.h" #include "CUIDCounter.h"
#include "prefs.h" #include "prefs.h"
#include "LogFactory.h"
#include "Logger.h"
#include "Util.h"
BtSetup::BtSetup():_logger(LogFactory::getInstance()) {}
Commands BtSetup::setup(RequestGroup* requestGroup, Commands BtSetup::setup(RequestGroup* requestGroup,
DownloadEngine* e, DownloadEngine* e,
@ -92,6 +98,24 @@ Commands BtSetup::setup(RequestGroup* requestGroup,
unionCri)); unionCri));
} }
if(PeerListenCommand::getNumInstance() == 0) {
PeerListenCommand* listenCommand = PeerListenCommand::getInstance(e);
int32_t port;
int32_t listenPort = option->getAsInt(PREF_LISTEN_PORT);
if(listenPort == -1) {
port = listenCommand->bindPort(6881, 6999);
} else {
port = listenCommand->bindPort(listenPort, listenPort);
}
if(port == -1) {
_logger->error(_("Errors occurred while binding port.\n"));
delete listenCommand;
} else {
BT_RUNTIME(btContext)->setListenPort(port);
commands.push_back(listenCommand);
}
}
BT_RUNTIME(btContext)->setReady(true); BT_RUNTIME(btContext)->setReady(true);
return commands; return commands;
} }

View File

@ -37,6 +37,7 @@
#include "common.h" #include "common.h"
class Logger;
class RequestGroup; class RequestGroup;
class DownloadEngine; class DownloadEngine;
class Option; class Option;
@ -44,7 +45,11 @@ class Command;
extern typedef deque<Command*> Commands; extern typedef deque<Command*> Commands;
class BtSetup { class BtSetup {
private:
const Logger* _logger;
public: public:
BtSetup();
Commands setup(RequestGroup* requestGroup, Commands setup(RequestGroup* requestGroup,
DownloadEngine* e, DownloadEngine* e,
const Option* option); const Option* option);

View File

@ -101,7 +101,7 @@ ConsoleStatCalc::calculateStat(const RequestGroupManHandle& requestGroupMan,
cout << " " cout << " "
<< "UP:" << "UP:"
<< fixed << setprecision(2) << stat.getUploadSpeed()/1024.0 << "KiB/s" << fixed << setprecision(2) << stat.getUploadSpeed()/1024.0 << "KiB/s"
<< "(" << Util::abbrevSize(stat.getAllTimeUploadLength()) << ")"; << "(" << Util::abbrevSize(stat.getAllTimeUploadLength()) << "B)";
} }
if(eta > 0) { if(eta > 0) {
cout << " " cout << " "

View File

@ -44,6 +44,7 @@
#include "prefs.h" #include "prefs.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "message.h" #include "message.h"
#include "SimpleRandomizer.h"
DefaultBtAnnounce::DefaultBtAnnounce(BtContextHandle btContext, DefaultBtAnnounce::DefaultBtAnnounce(BtContextHandle btContext,
const Option* option): const Option* option):
@ -56,20 +57,22 @@ DefaultBtAnnounce::DefaultBtAnnounce(BtContextHandle btContext,
announceList(btContext->getAnnounceTiers()), announceList(btContext->getAnnounceTiers()),
trackerNumTry(0), trackerNumTry(0),
option(option), option(option),
logger(LogFactory::getInstance()),
_randomizer(SimpleRandomizer::getInstance()),
btRuntime(BT_RUNTIME(btContext)), btRuntime(BT_RUNTIME(btContext)),
pieceStorage(PIECE_STORAGE(btContext)), pieceStorage(PIECE_STORAGE(btContext)),
peerStorage(PEER_STORAGE(btContext)) peerStorage(PEER_STORAGE(btContext))
{ {
prevAnnounceTime.setTimeInSec(0); prevAnnounceTime.setTimeInSec(0);
key = generateKey(); generateKey();
logger = LogFactory::getInstance();
} }
DefaultBtAnnounce::~DefaultBtAnnounce() { DefaultBtAnnounce::~DefaultBtAnnounce() {
} }
string DefaultBtAnnounce::generateKey() const { void DefaultBtAnnounce::generateKey()
return Util::randomAlpha(8); {
key = Util::randomAlpha(8, _randomizer);
} }
bool DefaultBtAnnounce::isDefaultAnnounceReady() { bool DefaultBtAnnounce::isDefaultAnnounceReady() {
@ -125,7 +128,6 @@ string DefaultBtAnnounce::getAnnounceUrl() {
"info_hash="+Util::torrentUrlencode(btContext->getInfoHash(), "info_hash="+Util::torrentUrlencode(btContext->getInfoHash(),
btContext->getInfoHashLength())+"&"+ btContext->getInfoHashLength())+"&"+
"peer_id="+Util::torrentUrlencode(btContext->getPeerId(), 20)+"&"+ "peer_id="+Util::torrentUrlencode(btContext->getPeerId(), 20)+"&"+
"port="+Util::itos(btRuntime->getListenPort())+"&"+
"uploaded="+Util::llitos(stat.getSessionUploadLength())+"&"+ "uploaded="+Util::llitos(stat.getSessionUploadLength())+"&"+
"downloaded="+Util::llitos(stat.getSessionDownloadLength())+"&"+ "downloaded="+Util::llitos(stat.getSessionDownloadLength())+"&"+
"left="+Util::llitos(left)+"&"+ "left="+Util::llitos(left)+"&"+
@ -133,6 +135,9 @@ string DefaultBtAnnounce::getAnnounceUrl() {
"key="+key+"&"+ "key="+key+"&"+
"numwant="+Util::itos(numWant)+"&"+ "numwant="+Util::itos(numWant)+"&"+
"no_peer_id=1"; "no_peer_id=1";
if(btRuntime->getListenPort() > 0) {
url += string("&")+"port="+Util::itos(btRuntime->getListenPort());
}
string event = announceList.getEventString(); string event = announceList.getEventString();
if(!event.empty()) { if(!event.empty()) {
url += string("&")+"event="+event; url += string("&")+"event="+event;
@ -171,7 +176,7 @@ void DefaultBtAnnounce::resetAnnounce() {
void void
DefaultBtAnnounce::processAnnounceResponse(const char* trackerResponse, DefaultBtAnnounce::processAnnounceResponse(const char* trackerResponse,
size_t trackerResponseLength) size_t trackerResponseLength)
{ {
SharedHandle<MetaEntry> entry(MetaFileUtil::bdecoding(trackerResponse, SharedHandle<MetaEntry> entry(MetaFileUtil::bdecoding(trackerResponse,
trackerResponseLength)); trackerResponseLength));
@ -237,3 +242,8 @@ bool DefaultBtAnnounce::noMoreAnnounce() {
void DefaultBtAnnounce::shuffleAnnounce() { void DefaultBtAnnounce::shuffleAnnounce() {
announceList.shuffle(); announceList.shuffle();
} }
void DefaultBtAnnounce::setRandomizer(const RandomizerHandle& randomizer)
{
_randomizer = randomizer;
}

View File

@ -45,6 +45,9 @@
#include "PieceStorage.h" #include "PieceStorage.h"
#include "PeerStorage.h" #include "PeerStorage.h"
class Randomizer;
extern typedef SharedHandle<Randomizer> RandomizerHandle;
#define DEFAULT_ANNOUNCE_INTERVAL 1800 #define DEFAULT_ANNOUNCE_INTERVAL 1800
class DefaultBtAnnounce : public BtAnnounce { class DefaultBtAnnounce : public BtAnnounce {
@ -62,6 +65,7 @@ private:
int32_t trackerNumTry; int32_t trackerNumTry;
const Option* option; const Option* option;
Logger* logger; Logger* logger;
RandomizerHandle _randomizer;
BtRuntimeHandle btRuntime; BtRuntimeHandle btRuntime;
PieceStorageHandle pieceStorage; PieceStorageHandle pieceStorage;
PeerStorageHandle peerStorage; PeerStorageHandle peerStorage;
@ -111,7 +115,9 @@ public:
virtual void shuffleAnnounce(); virtual void shuffleAnnounce();
string generateKey() const; void generateKey();
void setRandomizer(const RandomizerHandle& randomizer);
}; };
#endif // _D_DEFAULT_BT_ANNOUNCE_H_ #endif // _D_DEFAULT_BT_ANNOUNCE_H_

View File

@ -43,15 +43,18 @@
#include "MessageDigestHelper.h" #include "MessageDigestHelper.h"
#include "a2netcompat.h" #include "a2netcompat.h"
#include "AnnounceTier.h" #include "AnnounceTier.h"
#include "SimpleRandomizer.h"
#include <libgen.h> #include <libgen.h>
DefaultBtContext::DefaultBtContext():_peerIdPrefix("-aria2-"), _ownerRequestGroup(0) {} DefaultBtContext::DefaultBtContext():_peerIdPrefix("-aria2-"),
_randomizer(SimpleRandomizer::getInstance()),
_ownerRequestGroup(0) {}
DefaultBtContext::~DefaultBtContext() {} DefaultBtContext::~DefaultBtContext() {}
string DefaultBtContext::generatePeerId() const { string DefaultBtContext::generatePeerId() const {
string peerId = _peerIdPrefix; string peerId = _peerIdPrefix;
peerId += Util::randomAlpha(20-_peerIdPrefix.size()); peerId += Util::randomAlpha(20-_peerIdPrefix.size(), _randomizer);
if(peerId.size() > 20) { if(peerId.size() > 20) {
peerId.erase(20); peerId.erase(20);
} }
@ -342,3 +345,7 @@ ostream& operator<<(ostream& o, const DefaultBtContext& ctx)
return o; return o;
} }
void DefaultBtContext::setRandomizer(const RandomizerHandle& randomizer)
{
_randomizer = randomizer;
}

View File

@ -39,6 +39,10 @@
#include "Dictionary.h" #include "Dictionary.h"
#include "Data.h" #include "Data.h"
#include "List.h" #include "List.h"
class Randomizer;
extern typedef SharedHandle<Randomizer> RandomizerHandle;
#define INFO_HASH_LENGTH 20 #define INFO_HASH_LENGTH 20
#define PIECE_HASH_LENGTH 20 #define PIECE_HASH_LENGTH 20
@ -58,6 +62,7 @@ private:
string peerId; string peerId;
string _peerIdPrefix; string _peerIdPrefix;
AnnounceTiers announceTiers; AnnounceTiers announceTiers;
RandomizerHandle _randomizer;
RequestGroup* _ownerRequestGroup; RequestGroup* _ownerRequestGroup;
@ -150,6 +155,8 @@ private:
_ownerRequestGroup = owner; _ownerRequestGroup = owner;
} }
void setRandomizer(const RandomizerHandle& randomizer);
friend ostream& operator<<(ostream& o, const DefaultBtContext& ctx); friend ostream& operator<<(ostream& o, const DefaultBtContext& ctx);
}; };

View File

@ -88,7 +88,7 @@ bool DownloadCommand::executeInternal() {
int32_t BUFSIZE = 16*1024; int32_t BUFSIZE = 16*1024;
char buf[BUFSIZE]; char buf[BUFSIZE];
int32_t bufSize; int32_t bufSize;
if(segment->getLength()-segment->getWrittenLength() < BUFSIZE) { if(segment->getLength() > 0 && segment->getLength()-segment->getWrittenLength() < BUFSIZE) {
bufSize = segment->getLength()-segment->getWrittenLength(); bufSize = segment->getLength()-segment->getWrittenLength();
} else { } else {
bufSize = BUFSIZE; bufSize = BUFSIZE;
@ -157,31 +157,16 @@ bool DownloadCommand::prepareForNextSegment() {
*/ */
return true; return true;
} else { } else {
// Merge segment with next segment, if segment.index+1 == nextSegment.index
SegmentHandle tempSegment = _segments.front(); SegmentHandle tempSegment = _segments.front();
while(1) { SegmentHandle nextSegment =
SegmentHandle nextSegment = _requestGroup->getSegmentMan()->getSegment(cuid,
_requestGroup->getSegmentMan()->getSegment(cuid, tempSegment->getIndex()+1);
tempSegment->getIndex()+1); if(!nextSegment.isNull() && nextSegment->getWrittenLength() == 0) {
if(nextSegment.isNull()) { e->commands.push_back(this);
break; return false;
} else { } else {
if(nextSegment->getWrittenLength() > 0) { return prepareForRetry(0);
return prepareForRetry(0);
}
nextSegment->updateWrittenLength(tempSegment->getOverflowLength());
if(nextSegment->complete()) {
validatePieceHash(nextSegment);
tempSegment = nextSegment;
} else {
e->commands.push_back(this);
return false;
}
}
} }
return prepareForRetry(0);
} }
} }

View File

@ -49,7 +49,6 @@
#include "FileAllocationDispatcherCommand.h" #include "FileAllocationDispatcherCommand.h"
#include "AutoSaveCommand.h" #include "AutoSaveCommand.h"
#include "HaveEraseCommand.h" #include "HaveEraseCommand.h"
#include "PeerListenCommand.h"
DownloadEngineFactory::DownloadEngineFactory(): DownloadEngineFactory::DownloadEngineFactory():
_logger(LogFactory::getInstance()) {} _logger(LogFactory::getInstance()) {}
@ -84,23 +83,5 @@ DownloadEngineFactory::newDownloadEngine(Option* op,
e->commands.push_back(new AutoSaveCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get(), op->getAsInt(PREF_AUTO_SAVE_INTERVAL))); e->commands.push_back(new AutoSaveCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get(), op->getAsInt(PREF_AUTO_SAVE_INTERVAL)));
e->commands.push_back(new HaveEraseCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get(), 10)); e->commands.push_back(new HaveEraseCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get(), 10));
PeerListenCommand* listenCommand =
new PeerListenCommand(CUIDCounterSingletonHolder::instance()->newID(), e.get());
int32_t port;
int32_t listenPort = op->getAsInt(PREF_LISTEN_PORT);
if(listenPort == -1) {
port = listenCommand->bindPort(6881, 6999);
} else {
port = listenCommand->bindPort(listenPort, listenPort);
}
if(port == -1) {
_logger->error(_("Errors occurred while binding port.\n"));
delete listenCommand;
} else {
op->put(PREF_LISTEN_PORT, Util::itos(port).c_str());
e->commands.push_back(listenCommand);
}
//btRuntime->setListenPort(port);
return e; return e;
} }

View File

@ -41,14 +41,26 @@
#include "message.h" #include "message.h"
#include "PeerReceiveHandshakeCommand.h" #include "PeerReceiveHandshakeCommand.h"
int32_t PeerListenCommand::__numInstance = 0;
PeerListenCommand* PeerListenCommand::__instance = 0;
PeerListenCommand::PeerListenCommand(int32_t cuid, DownloadEngine* e): PeerListenCommand::PeerListenCommand(int32_t cuid, DownloadEngine* e):
Command(cuid), Command(cuid),
e(e), e(e),
_lowestSpeedLimit(20*1024) {} _lowestSpeedLimit(20*1024)
{
++__numInstance;
}
PeerListenCommand::~PeerListenCommand() {} PeerListenCommand::~PeerListenCommand()
{
--__numInstance;
}
int32_t PeerListenCommand::bindPort(int32_t portRangeStart, int32_t portRangeEnd) { int32_t PeerListenCommand::bindPort(int32_t portRangeStart,
int32_t portRangeEnd)
{
if(portRangeStart > portRangeEnd) { if(portRangeStart > portRangeEnd) {
return -1; return -1;
} }
@ -103,3 +115,11 @@ bool PeerListenCommand::execute() {
e->commands.push_back(this); e->commands.push_back(this);
return false; return false;
} }
PeerListenCommand* PeerListenCommand::getInstance(DownloadEngine* e)
{
if(__numInstance == 0) {
__instance = new PeerListenCommand(CUIDCounterSingletonHolder::instance()->newID(), e);
}
return __instance;
}

View File

@ -45,6 +45,11 @@ private:
DownloadEngine* e; DownloadEngine* e;
SocketHandle socket; SocketHandle socket;
int32_t _lowestSpeedLimit; int32_t _lowestSpeedLimit;
static int32_t __numInstance;
static PeerListenCommand* __instance;
public: public:
PeerListenCommand(int32_t cuid, DownloadEngine* e); PeerListenCommand(int32_t cuid, DownloadEngine* e);
@ -58,6 +63,14 @@ public:
{ {
_lowestSpeedLimit = speed; _lowestSpeedLimit = speed;
} }
static PeerListenCommand* getInstance(DownloadEngine* e);
static int32_t getNumInstance()
{
return __numInstance;
}
}; };
#endif // _D_PEER_LISTEN_COMMAND_H_ #endif // _D_PEER_LISTEN_COMMAND_H_

View File

@ -82,11 +82,17 @@ bool TrackerWatcherCommand::execute() {
btAnnounce->announceSuccess(); btAnnounce->announceSuccess();
btAnnounce->resetAnnounce(); btAnnounce->resetAnnounce();
} catch(DlAbortEx* ex) { } catch(DlAbortEx* ex) {
logger->error(EX_EXCEPTION_CAUGHT, ex);
delete ex;
btAnnounce->announceFailure();
btAnnounce->resetAnnounce();
} catch(DlRetryEx* ex) {
logger->error(EX_EXCEPTION_CAUGHT, ex);
delete ex;
btAnnounce->announceFailure(); btAnnounce->announceFailure();
if(btAnnounce->isAllAnnounceFailed()) { if(btAnnounce->isAllAnnounceFailed()) {
btAnnounce->resetAnnounce(); btAnnounce->resetAnnounce();
} }
delete ex;
} }
_trackerRequestGroup = 0; _trackerRequestGroup = 0;
} else if(_trackerRequestGroup->getNumCommand() == 0){ } else if(_trackerRequestGroup->getNumCommand() == 0){

View File

@ -35,7 +35,7 @@
#include "Util.h" #include "Util.h"
#include "File.h" #include "File.h"
#include "message.h" #include "message.h"
#include "SimpleRandomizer.h" #include "Randomizer.h"
#include "a2netcompat.h" #include "a2netcompat.h"
#include "a2time.h" #include "a2time.h"
#include <ctype.h> #include <ctype.h>
@ -522,11 +522,11 @@ int32_t Util::countBit(uint32_t n) {
nbits[(n >> 24)&0xffu]; nbits[(n >> 24)&0xffu];
} }
string Util::randomAlpha(int32_t length) { string Util::randomAlpha(int32_t length, const RandomizerHandle& randomizer) {
static char *random_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static char *random_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
string str; string str;
for(int32_t i = 0; i < length; i++) { for(int32_t i = 0; i < length; i++) {
int32_t index = SimpleRandomizer::getInstance()->getRandomNumber(strlen(random_chars)); int32_t index = randomizer->getRandomNumber(strlen(random_chars));
str += random_chars[index]; str += random_chars[index];
} }
return str; return str;

View File

@ -43,6 +43,9 @@
#include <deque> #include <deque>
#include <ostream> #include <ostream>
class Randomizer;
extern typedef SharedHandle<Randomizer> RandomizerHandle;
#define STRTOLL(X) strtoll(X, (char**)NULL, 10) #define STRTOLL(X) strtoll(X, (char**)NULL, 10)
#define START_INDEX(OFFSET, PIECE_LENGTH) ((OFFSET)/(PIECE_LENGTH)) #define START_INDEX(OFFSET, PIECE_LENGTH) ((OFFSET)/(PIECE_LENGTH))
@ -112,7 +115,7 @@ public:
static int32_t countBit(uint32_t n); static int32_t countBit(uint32_t n);
static string randomAlpha(int32_t length); static string randomAlpha(int32_t length, const RandomizerHandle& randomizer);
static string toUpper(const string& src); static string toUpper(const string& src);

View File

@ -3,6 +3,12 @@
#include "Option.h" #include "Option.h"
#include "Util.h" #include "Util.h"
#include "Exception.h" #include "Exception.h"
#include "MockBtContext.h"
#include "MockPieceStorage.h"
#include "MockPeerStorage.h"
#include "BtRuntime.h"
#include "AnnounceTier.h"
#include "FixedNumberRandomizer.h"
#include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/HelperMacros.h>
using namespace std; using namespace std;
@ -11,27 +17,161 @@ class DefaultBtAnnounceTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(DefaultBtAnnounceTest); CPPUNIT_TEST_SUITE(DefaultBtAnnounceTest);
CPPUNIT_TEST(testIsDefaultAnnounceReady); CPPUNIT_TEST(testIsDefaultAnnounceReady);
CPPUNIT_TEST(testGetAnnounceUrl);
CPPUNIT_TEST(testNoMoreAnnounce);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
BtContextHandle btContext; MockBtContextHandle _btContext;
Option* option; MockPieceStorageHandle _pieceStorage;
MockPeerStorageHandle _peerStorage;
BtRuntimeHandle _btRuntime;
Option* _option;
public: public:
DefaultBtAnnounceTest():btContext(0) {} DefaultBtAnnounceTest():_btContext(0),
_pieceStorage(0),
_peerStorage(0),
_btRuntime(0) {}
void setUp() { void setUp() {
btContext = BtContextHandle(new DefaultBtContext()); _option = new Option();
btContext->load("test.torrent");
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 };
string peerId = "-aria2-ultrafastdltl";
_btContext = new MockBtContext();
_btContext->setInfoHash(infoHash);
_btContext->setTotalLength(totalLength);
_btContext->setPieceLength(pieceLength);
_btContext->setPeerId((const unsigned char*)peerId.c_str());
_pieceStorage = new MockPieceStorage();
_pieceStorage->setTotalLength(totalLength);
_pieceStorage->setCompletedLength(pieceLength*10);
_peerStorage = new MockPeerStorage();
TransferStat stat;
stat.setSessionDownloadLength(pieceLength*5);
stat.setSessionUploadLength(pieceLength*6);
_peerStorage->setStat(stat);
_btRuntime = new BtRuntime();
_btRuntime->setListenPort(6989);
}
void tearDown()
{
delete _option;
} }
void testIsDefaultAnnounceReady(); void testIsDefaultAnnounceReady();
void testGetAnnounceUrl();
void testNoMoreAnnounce();
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtAnnounceTest); CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtAnnounceTest);
void DefaultBtAnnounceTest::testIsDefaultAnnounceReady() { void DefaultBtAnnounceTest::testIsDefaultAnnounceReady() {
DefaultBtAnnounce btAnnounce(btContext, option); DefaultBtAnnounce btAnnounce(_btContext, _option);
CPPUNIT_ASSERT(btAnnounce.isDefaultAnnounceReady()); CPPUNIT_ASSERT(btAnnounce.isDefaultAnnounceReady());
} }
void DefaultBtAnnounceTest::testNoMoreAnnounce()
{
string trackerURI1 = "http://localhost/announce";
Strings uris1;
uris1.push_back(trackerURI1);
AnnounceTierHandle announceTier1 = new AnnounceTier(uris1);
string trackerURI2 = "http://backup/announce";
Strings uris2;
uris2.push_back(trackerURI2);
AnnounceTierHandle announceTier2 = new AnnounceTier(uris2);
_btContext->addAnnounceTier(announceTier1);
_btContext->addAnnounceTier(announceTier2);
DefaultBtAnnounce btAnnounce(_btContext, _option);
btAnnounce.setPieceStorage(_pieceStorage);
btAnnounce.setPeerStorage(_peerStorage);
btAnnounce.setBtRuntime(_btRuntime);
btAnnounce.setRandomizer(new FixedNumberRandomizer());
btAnnounce.generateKey();
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989"), btAnnounce.getAnnounceUrl());
btAnnounce.announceFailure();
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_pieceStorage->setAllDownloadFinished(true);
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_btRuntime->setHalt(true);
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
}
void DefaultBtAnnounceTest::testGetAnnounceUrl()
{
string trackerURI = "http://localhost/announce";
Strings uris;
uris.push_back(trackerURI);
AnnounceTierHandle announceTier = new AnnounceTier(uris);
_btContext->addAnnounceTier(announceTier);
DefaultBtAnnounce btAnnounce(_btContext, _option);
btAnnounce.setPieceStorage(_pieceStorage);
btAnnounce.setPeerStorage(_peerStorage);
btAnnounce.setBtRuntime(_btRuntime);
btAnnounce.setRandomizer(new FixedNumberRandomizer());
btAnnounce.generateKey();
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=started"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_pieceStorage->setAllDownloadFinished(true);
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=50&no_peer_id=1&port=6989&event=completed"), btAnnounce.getAnnounceUrl());
btAnnounce.announceSuccess();
_btRuntime->setHalt(true);
CPPUNIT_ASSERT_EQUAL(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=AAAAAAAA&numwant=0&no_peer_id=1&port=6989&event=stopped"), btAnnounce.getAnnounceUrl());
}

View File

@ -2,6 +2,7 @@
#include "Util.h" #include "Util.h"
#include "Exception.h" #include "Exception.h"
#include "AnnounceTier.h" #include "AnnounceTier.h"
#include "FixedNumberRandomizer.h"
#include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/HelperMacros.h>
using namespace std; using namespace std;
@ -229,7 +230,8 @@ void DefaultBtContextTest::testGetInfoHashAsString() {
void DefaultBtContextTest::testGetPeerId() { void DefaultBtContextTest::testGetPeerId() {
DefaultBtContext btContext; DefaultBtContext btContext;
Util::torrentUrlencode(btContext.getPeerId(), 20); btContext.setRandomizer(new FixedNumberRandomizer());
CPPUNIT_ASSERT_EQUAL(string("%2daria2%2dAAAAAAAAAAAAA"), Util::torrentUrlencode(btContext.getPeerId(), 20));
} }
void DefaultBtContextTest::testComputeFastSet() void DefaultBtContextTest::testComputeFastSet()

View File

@ -18,8 +18,18 @@ private:
DiskAdaptorHandle diskAdaptor; DiskAdaptorHandle diskAdaptor;
Integers pieceLengthList; Integers pieceLengthList;
Pieces inFlightPieces; Pieces inFlightPieces;
bool _allDownloadFinished;
public: public:
MockPieceStorage():diskAdaptor(0) {} MockPieceStorage():totalLength(0),
filteredTotalLength(0),
completedLength(0),
filteredCompletedLength(0),
bitfieldMan(0),
selectiveDownloadingMode(false),
endGame(false),
diskAdaptor(0),
_allDownloadFinished(false) {}
virtual ~MockPieceStorage() {} virtual ~MockPieceStorage() {}
virtual bool hasMissingPiece(const PeerHandle& peer) { virtual bool hasMissingPiece(const PeerHandle& peer) {
@ -108,7 +118,12 @@ public:
} }
virtual bool allDownloadFinished() { virtual bool allDownloadFinished() {
return false; return _allDownloadFinished;
}
void setAllDownloadFinished(bool f)
{
_allDownloadFinished = f;
} }
virtual void initStorage() {} virtual void initStorage() {}

View File

@ -1,4 +1,5 @@
#include "Util.h" #include "Util.h"
#include "FixedNumberRandomizer.h"
#include <string> #include <string>
#include <cppunit/extensions/HelperMacros.h> #include <cppunit/extensions/HelperMacros.h>
@ -240,7 +241,8 @@ public:
}; };
void UtilTest::testRandomAlpha() { void UtilTest::testRandomAlpha() {
CPPUNIT_ASSERT_EQUAL((size_t)8, Util::randomAlpha(8).size()); string s = Util::randomAlpha(8, new FixedNumberRandomizer());
CPPUNIT_ASSERT_EQUAL(string("AAAAAAAA"), s);
} }
void UtilTest::testToUpper() { void UtilTest::testToUpper() {