2006-10-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

To simplify TrackerWatherCommand, TrackerUpdateCommand and
	make the process of announce request testable.
	
	* src/TrackerWatcherCommand.h
	(TimeA2.h): Removed.
	(interval): Removed.
	(checkPoint): Removed.
	(createRequestCommand): Added an argument 'url'.
	(TrackerWatherCommand): Removed interval.
	(createCommand): New function.
	* src/DownloadEngineFactory.cc
	(newTorrentConsoleEngine): Updated according to the changes in
	TrackerWatherCommand.
	* src/TorrentMan.cc
	(DelegatingPeerListProcessor.h): New includes.
	(TorrentMan): Added the initialization of announceInterval.
	(isStoppedAnnounceReady): New function.
	(isCompletedAnnounceReady): New function.
	(isDefaultAnnounceReady): New function.
	(isAnnounceReady): New function.
	(getAnnounceUrl): New function.
	(announceStart): New function.
	(announceFailure): New function.
	(announceSuccess): New function.
	(isAllAnnounceFailed): New function.
	(resetAnnounce): New function.
	(processAnnounceResponse): New function.
	(needMorePeerConnection): New function.
	(noMoreAnnounce): New function.
	* src/TrackerUpdateCommand.h
	(getTrackerResponse): int->size_t
	* src/TorrentMan.h
	(isStoppedAnnounceReady): New function.
	(isCompletedAnnounceReady): New function.
	(isDefaultAnnounceReady): New function.
	(announceInterval): New variable.
	(isAnnounceReady): New function.
	(getAnnounceUrl): New function.
	(announceStart): New function.
	(announceFailure): New function.
	(announceSuccess): New function.
	(isAllAnnounceFailed): New function.
	(resetAnnounce): New function.
	(processAnnounceResponse): New function.
	(needMorePeerConnection): New function.
	(noMoreAnnounce): New function.
	* src/TrackerWatcherCommand.cc
	(TrackerWatherCommand): Removed interval and checkPoint.
	(execute): Rewritten.
	(createCommand): New function.
	(createRequestCommand): Rewritten.
	* src/TrackerUpdateCommand.cc
	(MetaFileUtil.h): Removed.
	(DelegatingPeerListProcessor.h): Removed.
	(getTrackerResponse): int->size_t. Use torrentMan's new 
functions.
pull/1/head
Tatsuhiro Tsujikawa 2006-10-20 13:20:50 +00:00
parent c0fd1fff2a
commit b8737b0e7c
13 changed files with 369 additions and 169 deletions

View File

@ -1,3 +1,61 @@
2006-10-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
To simplify TrackerWatherCommand, TrackerUpdateCommand and
make the process of announce request testable.
* src/TrackerWatcherCommand.h
(TimeA2.h): Removed.
(interval): Removed.
(checkPoint): Removed.
(createRequestCommand): Added an argument 'url'.
(TrackerWatherCommand): Removed interval.
(createCommand): New function.
* src/DownloadEngineFactory.cc
(newTorrentConsoleEngine): Updated according to the changes in
TrackerWatherCommand.
* src/TorrentMan.cc
(DelegatingPeerListProcessor.h): New includes.
(TorrentMan): Added the initialization of announceInterval.
(isStoppedAnnounceReady): New function.
(isCompletedAnnounceReady): New function.
(isDefaultAnnounceReady): New function.
(isAnnounceReady): New function.
(getAnnounceUrl): New function.
(announceStart): New function.
(announceFailure): New function.
(announceSuccess): New function.
(isAllAnnounceFailed): New function.
(resetAnnounce): New function.
(processAnnounceResponse): New function.
(needMorePeerConnection): New function.
(noMoreAnnounce): New function.
* src/TrackerUpdateCommand.h
(getTrackerResponse): int->size_t
* src/TorrentMan.h
(isStoppedAnnounceReady): New function.
(isCompletedAnnounceReady): New function.
(isDefaultAnnounceReady): New function.
(announceInterval): New variable.
(isAnnounceReady): New function.
(getAnnounceUrl): New function.
(announceStart): New function.
(announceFailure): New function.
(announceSuccess): New function.
(isAllAnnounceFailed): New function.
(resetAnnounce): New function.
(processAnnounceResponse): New function.
(needMorePeerConnection): New function.
(noMoreAnnounce): New function.
* src/TrackerWatcherCommand.cc
(TrackerWatherCommand): Removed interval and checkPoint.
(execute): Rewritten.
(createCommand): New function.
(createRequestCommand): Rewritten.
* src/TrackerUpdateCommand.cc
(MetaFileUtil.h): Removed.
(DelegatingPeerListProcessor.h): Removed.
(getTrackerResponse): int->size_t. Use torrentMan's new functions.
2006-10-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com> 2006-10-18 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Request -> RequestHandle: Request -> RequestHandle:

View File

@ -114,8 +114,7 @@ DownloadEngineFactory::newTorrentConsoleEngine(const Option* op,
te->commands.push_back(listenCommand); te->commands.push_back(listenCommand);
te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(), te->commands.push_back(new TrackerWatcherCommand(te->torrentMan->getNewCuid(),
te, te));
te->torrentMan->minInterval));
te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(), te->commands.push_back(new TrackerUpdateCommand(te->torrentMan->getNewCuid(),
te)); te));
te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(), te->commands.push_back(new TorrentAutoSaveCommand(te->torrentMan->getNewCuid(),

View File

@ -49,6 +49,7 @@
#include "DirectDiskAdaptor.h" #include "DirectDiskAdaptor.h"
#include "MultiDiskAdaptor.h" #include "MultiDiskAdaptor.h"
#include "LogFactory.h" #include "LogFactory.h"
#include "DelegatingPeerListProcessor.h"
#include <errno.h> #include <errno.h>
#include <libgen.h> #include <libgen.h>
#include <string.h> #include <string.h>
@ -76,6 +77,8 @@ TorrentMan::TorrentMan():bitfield(0),
diskAdaptor(0) diskAdaptor(0)
{ {
logger = LogFactory::getInstance(); logger = LogFactory::getInstance();
// to force requesting to a tracker first time.
announceInterval.setTimeInSec(0);
} }
TorrentMan::~TorrentMan() { TorrentMan::~TorrentMan() {
@ -751,3 +754,158 @@ TransferStat TorrentMan::calculateStat() {
} }
return stat; return stat;
} }
bool TorrentMan::isStoppedAnnounceReady() const {
return (trackers == 0 &&
isHalt() &&
announceList.countStoppedAllowedTier());
}
bool TorrentMan::isCompletedAnnounceReady() const {
return (trackers == 0 &&
downloadComplete() &&
announceList.countCompletedAllowedTier());
}
bool TorrentMan::isDefaultAnnounceReady() const {
return (trackers == 0 &&
announceInterval.elapsed(minInterval));
}
bool TorrentMan::isAnnounceReady() const {
return
isStoppedAnnounceReady() ||
isCompletedAnnounceReady() ||
isDefaultAnnounceReady();
}
string TorrentMan::getAnnounceUrl() {
if(isStoppedAnnounceReady()) {
announceList.moveToStoppedAllowedTier();
announceList.setEvent(AnnounceTier::STOPPED);
} else if(isCompletedAnnounceReady()) {
announceList.moveToCompletedAllowedTier();
announceList.setEvent(AnnounceTier::COMPLETED);
} else if(isDefaultAnnounceReady()) {
// If download completed before "started" event is sent to a tracker,
// we change the event to something else to prevent us from
// sending "completed" event.
if(downloadComplete() &&
announceList.getEvent() == AnnounceTier::STARTED) {
announceList.setEvent(AnnounceTier::STARTED_AFTER_COMPLETION);
}
}
int numWant = 50;
if(connections >= MIN_PEERS || isHalt()) {
numWant = 0;
}
string url = announceList.getAnnounce()+"?"+
"info_hash="+Util::torrentUrlencode(getInfoHash(), 20)+"&"+
"peer_id="+peerId+"&"+
"port="+Util::itos(getPort())+"&"+
"uploaded="+Util::llitos(getSessionUploadLength())+"&"+
"downloaded="+Util::llitos(getSessionDownloadLength())+"&"+
"left="+(getTotalLength()-getDownloadLength() <= 0
? "0" : Util::llitos(getTotalLength()-getDownloadLength()))+"&"+
"compact=1"+"&"+
"key="+key+"&"+
"numwant="+Util::itos(numWant)+"&"+
"no_peer_id=1";
string event = announceList.getEventString();
if(!event.empty()) {
url += string("&")+"event="+event;
}
if(!trackerId.empty()) {
url += string("&")+"trackerid="+trackerId;
}
return url;
}
void TorrentMan::announceStart() {
trackers++;
}
void TorrentMan::announceFailure() {
trackers = 0;
trackerNumTry++;
announceList.announceFailure();
}
void TorrentMan::announceSuccess() {
trackers = 0;
announceList.announceSuccess();
}
bool TorrentMan::isAllAnnounceFailed() const {
return
trackerNumTry >= option->getAsInt(PREF_TRACKER_MAX_TRIES);
}
void TorrentMan::resetAnnounce() {
announceInterval.reset();
trackerNumTry = 0;
}
void TorrentMan::processAnnounceResponse(const char* trackerResponse,
size_t trackerResponseLength) {
SharedHandle<MetaEntry> entry(MetaFileUtil::bdecoding(trackerResponse,
trackerResponseLength));
Dictionary* response = (Dictionary*)entry.get();
Data* failureReasonData = (Data*)response->get("failure reason");
if(failureReasonData) {
throw new DlAbortEx("Tracker returned failure reason: %s",
failureReasonData->toString().c_str());
}
Data* warningMessageData = (Data*)response->get("warning message");
if(warningMessageData) {
logger->warn(MSG_TRACKER_WARNING_MESSAGE,
warningMessageData->toString().c_str());
}
Data* trackerIdData = (Data*)response->get("tracker id");
if(trackerIdData) {
trackerId = trackerIdData->toString();
logger->debug("Tracker ID:%s", trackerId.c_str());
}
Data* intervalData = (Data*)response->get("interval");
if(intervalData) {
interval = intervalData->toInt();
logger->debug("Interval:%d", interval);
}
Data* minIntervalData = (Data*)response->get("min interval");
if(minIntervalData) {
minInterval = minIntervalData->toInt();
logger->debug("Min interval:%d", minInterval);
}
if(minInterval > interval) {
minInterval = interval;
}
Data* completeData = (Data*)response->get("complete");
if(completeData) {
complete = completeData->toInt();
logger->debug("Complete:%d", complete);
}
Data* incompleteData = (Data*)response->get("incomplete");
if(incompleteData) {
incomplete = incompleteData->toInt();
logger->debug("Incomplete:%d", incomplete);
}
const MetaEntry* peersEntry = response->get("peers");
if(peersEntry && !isHalt() && connections < MIN_PEERS) {
DelegatingPeerListProcessor proc(pieceLength, getTotalLength());
Peers peers = proc.extractPeer(peersEntry);
addPeer(peers);
}
if(!peersEntry) {
logger->info("No peer list received.");
}
}
bool TorrentMan::needMorePeerConnection() const {
return isPeerAvailable() && connections < MIN_PEERS;
}
bool TorrentMan::noMoreAnnounce() const {
return (trackers == 0 &&
isHalt() &&
!announceList.countStoppedAllowedTier());
}

View File

@ -126,6 +126,10 @@ private:
void setupInternal1(const string& metaInfoFile); void setupInternal1(const string& metaInfoFile);
void setupInternal2(); void setupInternal2();
Piece checkOutPiece(int index); Piece checkOutPiece(int index);
bool isStoppedAnnounceReady() const;
bool isCompletedAnnounceReady() const;
bool isDefaultAnnounceReady() const;
public: public:
int pieceLength; int pieceLength;
int pieces; int pieces;
@ -143,6 +147,7 @@ public:
// The number of tracker request command currently in the command queue. // The number of tracker request command currently in the command queue.
int trackers; int trackers;
int trackerNumTry; int trackerNumTry;
Time announceInterval;
// tracker request // tracker request
AnnounceList announceList; AnnounceList announceList;
public: public:
@ -297,6 +302,18 @@ public:
void setHalt(bool halt) { void setHalt(bool halt) {
this->halt = halt; this->halt = halt;
} }
// announce related methods.
bool isAnnounceReady() const;
string getAnnounceUrl();
void announceStart();
void announceSuccess();
void announceFailure();
bool isAllAnnounceFailed() const;
void resetAnnounce();
void processAnnounceResponse(const char* trackerResponse,
size_t trackerResponseLength);
bool needMorePeerConnection() const;
bool noMoreAnnounce() const;
enum FILE_MODE { enum FILE_MODE {
SINGLE, SINGLE,

View File

@ -34,15 +34,13 @@
/* copyright --> */ /* copyright --> */
#include "TrackerUpdateCommand.h" #include "TrackerUpdateCommand.h"
#include "LogFactory.h" #include "LogFactory.h"
#include "MetaFileUtil.h"
#include "DlAbortEx.h" #include "DlAbortEx.h"
#include "message.h" #include "message.h"
#include "PeerInitiateConnectionCommand.h" #include "PeerInitiateConnectionCommand.h"
#include "SleepCommand.h" #include "SleepCommand.h"
#include "Util.h" #include "Util.h"
#include "DelegatingPeerListProcessor.h"
TrackerUpdateCommand::TrackerUpdateCommand(int cuid, TorrentDownloadEngine*e):Command(cuid), e(e) { TrackerUpdateCommand::TrackerUpdateCommand(int cuid, TorrentDownloadEngine* e):Command(cuid), e(e) {
logger = LogFactory::getInstance(); logger = LogFactory::getInstance();
} }
@ -53,7 +51,7 @@ bool TrackerUpdateCommand::prepareForRetry() {
return false; return false;
} }
char* TrackerUpdateCommand::getTrackerResponse(int& trackerResponseLength) { char* TrackerUpdateCommand::getTrackerResponse(size_t& trackerResponseLength) {
int maxBufLength = 2048; int maxBufLength = 2048;
char* buf = new char[maxBufLength]; char* buf = new char[maxBufLength];
int bufLength = 0; int bufLength = 0;
@ -86,77 +84,24 @@ bool TrackerUpdateCommand::execute() {
return prepareForRetry(); return prepareForRetry();
} }
char* trackerResponse = NULL; char* trackerResponse = NULL;
int trackerResponseLength = 0; size_t trackerResponseLength = 0;
try { try {
trackerResponse = getTrackerResponse(trackerResponseLength); trackerResponse = getTrackerResponse(trackerResponseLength);
SharedHandle<MetaEntry> entry(MetaFileUtil::bdecoding(trackerResponse,
trackerResponseLength));
Dictionary* response = (Dictionary*)entry.get();
Data* failureReason = (Data*)response->get("failure reason");
if(failureReason != NULL) {
throw new DlAbortEx("Tracker returned failure reason: %s", failureReason->toString().c_str());
}
Data* warningMessage = (Data*)response->get("warning message");
if(warningMessage != NULL) {
logger->warn(MSG_TRACKER_WARNING_MESSAGE, warningMessage->toString().c_str());
}
Data* trackerId = (Data*)response->get("tracker id");
if(trackerId != NULL) {
e->torrentMan->trackerId = trackerId->toString();
logger->debug("CUID#%d - Tracker ID:%s",
cuid, e->torrentMan->trackerId.c_str());
}
Data* interval = (Data*)response->get("interval");
if(interval != NULL) {
e->torrentMan->interval = interval->toInt();
logger->debug("CUID#%d - Interval:%d", cuid, e->torrentMan->interval);
}
Data* minInterval = (Data*)response->get("min interval");
if(minInterval != NULL) {
e->torrentMan->minInterval = minInterval->toInt();
logger->debug("CUID#%d - Min interval:%d",
cuid, e->torrentMan->minInterval);
}
if(e->torrentMan->minInterval > e->torrentMan->interval) {
e->torrentMan->minInterval = e->torrentMan->interval;
}
Data* complete = (Data*)response->get("complete");
if(complete != NULL) {
e->torrentMan->complete = complete->toInt();
logger->debug("CUID#%d - Complete:%d", cuid, e->torrentMan->complete);
}
Data* incomplete = (Data*)response->get("incomplete");
if(incomplete != NULL) {
e->torrentMan->incomplete = incomplete->toInt();
logger->debug("CUID#%d - Incomplete:%d",
cuid, e->torrentMan->incomplete);
}
const MetaEntry* peersEntry = response->get("peers");
if(!e->torrentMan->isHalt() &&
e->torrentMan->connections < MIN_PEERS &&
peersEntry) {
DelegatingPeerListProcessor proc(e->torrentMan->pieceLength,
e->torrentMan->getTotalLength());
Peers peers = proc.extractPeer(peersEntry);
e->torrentMan->addPeer(peers);
while(e->torrentMan->isPeerAvailable() && e->torrentMan->processAnnounceResponse(trackerResponse,
e->torrentMan->connections < MIN_PEERS) { trackerResponseLength);
PeerHandle peer = e->torrentMan->getPeer(); while(e->torrentMan->needMorePeerConnection()) {
int newCuid = e->torrentMan->getNewCuid(); PeerHandle peer = e->torrentMan->getPeer();
peer->cuid = newCuid; int newCuid = e->torrentMan->getNewCuid();
PeerInitiateConnectionCommand* command = peer->cuid = newCuid;
new PeerInitiateConnectionCommand(newCuid, peer, e); PeerInitiateConnectionCommand* command =
e->commands.push_back(command); new PeerInitiateConnectionCommand(newCuid, peer, e);
logger->debug("CUID#%d - Adding new command CUID#%d", cuid, newCuid); e->commands.push_back(command);
} logger->debug("CUID#%d - Adding new command CUID#%d", cuid, newCuid);
} }
if(!peersEntry) { e->torrentMan->announceSuccess();
logger->info("CUID#%d - No peer list received.", cuid); e->torrentMan->resetAnnounce();
}
e->torrentMan->announceList.announceSuccess();
e->torrentMan->trackers = 0;
e->segmentMan->init(); e->segmentMan->init();
} catch(Exception* err) { } catch(Exception* err) {
logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err); logger->error("CUID#%d - Error occurred while processing tracker response.", cuid, err);

View File

@ -44,7 +44,7 @@ private:
TorrentDownloadEngine* e; TorrentDownloadEngine* e;
const Logger* logger; const Logger* logger;
bool prepareForRetry(); bool prepareForRetry();
char* getTrackerResponse(int& trackerResponseLength); char* getTrackerResponse(size_t& trackerResponseLength);
public: public:
TrackerUpdateCommand(int cuid, TorrentDownloadEngine* e); TrackerUpdateCommand(int cuid, TorrentDownloadEngine* e);
virtual ~TrackerUpdateCommand(); virtual ~TrackerUpdateCommand();

View File

@ -39,103 +39,48 @@
#include "prefs.h" #include "prefs.h"
TrackerWatcherCommand::TrackerWatcherCommand(int cuid, TrackerWatcherCommand::TrackerWatcherCommand(int cuid,
TorrentDownloadEngine* e, TorrentDownloadEngine* e):
int interval): Command(cuid), e(e) {
Command(cuid), e(e), interval(interval) {
// to force requesting to a tracker first time.
checkPoint.setTimeInSec(0);
} }
TrackerWatcherCommand::~TrackerWatcherCommand() {} TrackerWatcherCommand::~TrackerWatcherCommand() {}
bool TrackerWatcherCommand::execute() {
Command* command = 0;
if(e->torrentMan->trackers == 0 && e->torrentMan->isHalt()) {
// Download is going to halt.
// Check whether there are at least one tracker which can receive
// "stopped" event.
if(e->torrentMan->announceList.countStoppedAllowedTier()) {
e->torrentMan->announceList.moveToStoppedAllowedTier();
e->torrentMan->announceList.setEvent(AnnounceTier::STOPPED);
command = createRequestCommand();
} else {
// We don't send "stopped" event since no tracker cares about it.
return true;
}
} else if(e->torrentMan->trackers == 0 &&
e->torrentMan->downloadComplete() &&
e->torrentMan->announceList.countCompletedAllowedTier()) {
// Send "completed" event to all trackers which can accept it.
e->torrentMan->announceList.moveToCompletedAllowedTier();
e->torrentMan->announceList.setEvent(AnnounceTier::COMPLETED);
command = createRequestCommand();
} else if(e->torrentMan->trackers == 0 &&
checkPoint.elapsed(interval)) {
checkPoint.reset();
// If download completed before "started" event is sent to a tracker,
// we change the event to something else to prevent us from
// sending "completed" event.
if(e->torrentMan->downloadComplete() &&
e->torrentMan->announceList.getEvent() == AnnounceTier::STARTED) {
e->torrentMan->announceList.setEvent(AnnounceTier::STARTED_AFTER_COMPLETION);
}
command = createRequestCommand();
} else if(e->segmentMan->errors > 0) {
e->torrentMan->trackerNumTry++;
checkPoint.reset();
// we assume the tracker request has failed.
e->torrentMan->announceList.announceFailure();
e->torrentMan->trackers = 0;
e->segmentMan->init();
if(e->torrentMan->trackerNumTry >= e->option->getAsInt(PREF_TRACKER_MAX_TRIES)) {
// abort tracker request
e->torrentMan->trackerNumTry = 0;
if(e->torrentMan->isHalt()) {
return true;
}
} else {
// sleep a few seconds.
command =
new SleepCommand(cuid, e,
createRequestCommand(),
e->option->getAsInt(PREF_RETRY_WAIT));
}
}
bool TrackerWatcherCommand::execute() {
if(e->torrentMan->isHalt() &&
e->segmentMan->errors > 0 && e->torrentMan->isAllAnnounceFailed() ||
e->torrentMan->noMoreAnnounce()) {
return true;
}
Command* command = createCommand();
if(command) { if(command) {
e->commands.push_back(command); e->commands.push_back(command);
e->torrentMan->trackers++;
} }
// updates interval with newest minInterval
interval = e->torrentMan->minInterval;
e->commands.push_back(this); e->commands.push_back(this);
return false; return false;
} }
Command* TrackerWatcherCommand::createRequestCommand() { Command* TrackerWatcherCommand::createCommand() {
int numWant = 50; Command* command = 0;
if(e->torrentMan->connections >= MIN_PEERS || e->torrentMan->isHalt()) { if(e->torrentMan->isAnnounceReady()) {
numWant = 0; command = createRequestCommand(e->torrentMan->getAnnounceUrl());
} e->torrentMan->announceStart(); // inside it, trackers++.
string url = e->torrentMan->announceList.getAnnounce()+"?"+ } else if(e->segmentMan->errors > 0) {
"info_hash="+Util::torrentUrlencode(e->torrentMan->getInfoHash(), 20)+"&"+ e->torrentMan->announceFailure(); // inside it, trackers = 0.
"peer_id="+e->torrentMan->peerId+"&"+ e->segmentMan->init();
"port="+Util::itos(e->torrentMan->getPort())+"&"+ if(e->torrentMan->isAllAnnounceFailed()) {
"uploaded="+Util::llitos(e->torrentMan->getSessionUploadLength())+"&"+ e->torrentMan->resetAnnounce();
"downloaded="+Util::llitos(e->torrentMan->getSessionDownloadLength())+"&"+ // sleep a few seconds.
"left="+(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength() <= 0 command =
? "0" : Util::llitos(e->torrentMan->getTotalLength()-e->torrentMan->getDownloadLength()))+"&"+ new SleepCommand(cuid, e,
"compact=1"+"&"+ createRequestCommand(e->torrentMan->getAnnounceUrl()),
"key="+e->torrentMan->key+"&"+ e->option->getAsInt(PREF_RETRY_WAIT));
"numwant="+Util::itos(numWant)+"&"+ }
"no_peer_id=1";
string event = e->torrentMan->announceList.getEventString();
if(!event.empty()) {
url += string("&")+"event="+event;
}
if(!e->torrentMan->trackerId.empty()) {
url += string("&")+"trackerid="+e->torrentMan->trackerId;
} }
return command;
}
Command* TrackerWatcherCommand::createRequestCommand(const string& url) {
RequestHandle req; RequestHandle req;
req->setUrl(url); req->setUrl(url);
req->isTorrent = true; req->isTorrent = true;

View File

@ -37,19 +37,22 @@
#include "Command.h" #include "Command.h"
#include "TorrentDownloadEngine.h" #include "TorrentDownloadEngine.h"
#include "TimeA2.h"
class TrackerWatcherCommand : public Command { class TrackerWatcherCommand : public Command {
private: private:
TorrentDownloadEngine* e; TorrentDownloadEngine* e;
int interval;
Time checkPoint;
Command* createRequestCommand(); /**
* Returns a command for announce request. Returns 0 if no announce request
* is needed.
*/
Command* createRequestCommand(const string& url);
public: public:
TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e, int interval); TrackerWatcherCommand(int cuid, TorrentDownloadEngine* e);
~TrackerWatcherCommand(); ~TrackerWatcherCommand();
Command* createCommand();
bool execute(); bool execute();
}; };

View File

@ -41,16 +41,19 @@ aria2c_SOURCES = AllTest.cc\
SegmentManTest.cc\ SegmentManTest.cc\
SpeedCalcTest.cc\ SpeedCalcTest.cc\
DefaultPeerListProcessorTest.cc\ DefaultPeerListProcessorTest.cc\
AnnounceListTest.cc AnnounceListTest.cc\
TrackerWatcherCommandTest.cc
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS} #aria2c_LDFLAGS = ${CPPUNIT_LIBS}
aria2c_LDADD = ../src/libaria2c.a\ aria2c_LDADD = ../src/libaria2c.a\
${CPPUNIT_LIBS} @LIBGNUTLS_LIBS@\ ${CPPUNIT_LIBS} @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@\
@LIBARES_LIBS@ @LIBCARES_LIBS@
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
${CPPUNIT_CFLAGS}\ ${CPPUNIT_CFLAGS}\
-I ../src\ -I ../src\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
@LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@

View File

@ -78,7 +78,7 @@ am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestTest.$(OBJEXT) \
ShareRatioSeedCriteriaTest.$(OBJEXT) \ ShareRatioSeedCriteriaTest.$(OBJEXT) \
TimeSeedCriteriaTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \ TimeSeedCriteriaTest.$(OBJEXT) SegmentManTest.$(OBJEXT) \
SpeedCalcTest.$(OBJEXT) DefaultPeerListProcessorTest.$(OBJEXT) \ SpeedCalcTest.$(OBJEXT) DefaultPeerListProcessorTest.$(OBJEXT) \
AnnounceListTest.$(OBJEXT) AnnounceListTest.$(OBJEXT) TrackerWatcherCommandTest.$(OBJEXT)
aria2c_OBJECTS = $(am_aria2c_OBJECTS) aria2c_OBJECTS = $(am_aria2c_OBJECTS)
am__DEPENDENCIES_1 = am__DEPENDENCIES_1 =
aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1) aria2c_DEPENDENCIES = ../src/libaria2c.a $(am__DEPENDENCIES_1)
@ -279,19 +279,22 @@ aria2c_SOURCES = AllTest.cc\
SegmentManTest.cc\ SegmentManTest.cc\
SpeedCalcTest.cc\ SpeedCalcTest.cc\
DefaultPeerListProcessorTest.cc\ DefaultPeerListProcessorTest.cc\
AnnounceListTest.cc AnnounceListTest.cc\
TrackerWatcherCommandTest.cc
#aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64 #aria2c_CXXFLAGS = ${CPPUNIT_CFLAGS} -I../src -I../lib -Wall -D_FILE_OFFSET_BITS=64
#aria2c_LDFLAGS = ${CPPUNIT_LIBS} #aria2c_LDFLAGS = ${CPPUNIT_LIBS}
aria2c_LDADD = ../src/libaria2c.a\ aria2c_LDADD = ../src/libaria2c.a\
${CPPUNIT_LIBS} @LIBGNUTLS_LIBS@\ ${CPPUNIT_LIBS} @LIBGNUTLS_LIBS@\
@LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@ @LIBGCRYPT_LIBS@ @OPENSSL_LIBS@ @XML_LIBS@\
@LIBARES_LIBS@ @LIBCARES_LIBS@
AM_CPPFLAGS = -Wall\ AM_CPPFLAGS = -Wall\
${CPPUNIT_CFLAGS}\ ${CPPUNIT_CFLAGS}\
-I ../src\ -I ../src\
-I../lib -I../intl -I$(top_srcdir)/intl\ -I../lib -I../intl -I$(top_srcdir)/intl\
@LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\ @LIBGNUTLS_CFLAGS@ @LIBGCRYPT_CFLAGS@ @OPENSSL_CFLAGS@ @XML_CPPFLAGS@\
@LIBARES_CPPFLAGS@ @LIBCARES_CPPFLAGS@\
-D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@ -D_FILE_OFFSET_BITS=64 -DLOCALEDIR=\"$(localedir)\" @DEFS@
all: all-am all: all-am
@ -379,6 +382,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessageTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SuggestPieceMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeSeedCriteriaTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentManTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TorrentManTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TrackerWatcherCommandTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessageTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnchokeMessageTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UtilTest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Xml2MetalinkProcessorTest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Xml2MetalinkProcessorTest.Po@am__quote@

View File

@ -55,6 +55,6 @@ void ShaVisitorTest::testVisitCompound() {
int len = 0; int len = 0;
v.getHash(md, len); v.getHash(md, len);
string hashHex = hexHash(md, len); string hashHex = hexHash(md, len);
CPPUNIT_ASSERT_EQUAL(string("9d33ba293924df85f6067a81c65b484de04e8efd"), CPPUNIT_ASSERT_EQUAL(string("0815f9b8137fbca179c8f560e20849174e9ede8b"),
hashHex); hashHex);
} }

View File

@ -0,0 +1,68 @@
#include "TrackerWatcherCommand.h"
#include "TorrentConsoleDownloadEngine.h"
#include "MetaFileUtil.h"
#include "Exception.h"
#include "prefs.h"
#include "HttpInitiateConnectionCommand.h"
#include "ByteArrayDiskWriter.h"
#include <cppunit/extensions/HelperMacros.h>
using namespace std;
class TrackerWatcherCommandTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(TrackerWatcherCommandTest);
CPPUNIT_TEST(testCreateCommand);
CPPUNIT_TEST_SUITE_END();
private:
public:
void setUp() {
}
void testCreateCommand();
};
CPPUNIT_TEST_SUITE_REGISTRATION( TrackerWatcherCommandTest );
void TrackerWatcherCommandTest::testCreateCommand() {
try {
Option* op = new Option();
op->put(PREF_TRACKER_MAX_TRIES, "10");
TorrentConsoleDownloadEngine* te = new TorrentConsoleDownloadEngine();
te->option = op;
te->segmentMan = new SegmentMan();
te->segmentMan->option = op;
ByteArrayDiskWriter* byteArrayDiskWriter = new ByteArrayDiskWriter();
te->segmentMan->diskWriter = byteArrayDiskWriter;
te->torrentMan = new TorrentMan();
te->torrentMan->option = op;
te->torrentMan->setup("test.torrent", Strings());
TrackerWatcherCommand command(1, te);
CPPUNIT_ASSERT(dynamic_cast<HttpInitiateConnectionCommand*>(command.createCommand()));
cerr << te->torrentMan->getAnnounceUrl() << endl;
te->torrentMan->announceSuccess();
te->torrentMan->resetAnnounce();
te->segmentMan->init();
te->torrentMan->setHalt(true);
CPPUNIT_ASSERT(dynamic_cast<HttpInitiateConnectionCommand*>(command.createCommand()));
cerr << te->torrentMan->getAnnounceUrl() << endl;
te->torrentMan->announceSuccess();
te->torrentMan->resetAnnounce();
te->segmentMan->init();
CPPUNIT_ASSERT(te->torrentMan->noMoreAnnounce());
} catch(Exception* e) {
cerr << e->getMsg() << endl;
delete e;
}
}

View File

@ -1 +1 @@
d8:announce36:http://aria.rednoah.com/announce.php7:comment17:REDNOAH.COM RULES13:creation datei1123456789e4:infod5:filesld6:lengthi256000e4:pathl5:aria23:src6:aria2ceed6:lengthi128900e4:pathl19:aria2-0.2.2.tar.bz2eee4:name10:aria2-test12:piece lengthi128e6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCee d8:announce36:http://aria.rednoah.com/announce.php13:announce-listll15:http://tracker1el15:http://tracker2el15:http://tracker3ee7:comment17:REDNOAH.COM RULES13:creation datei1123456789e4:infod5:filesld6:lengthi284e4:pathl5:aria23:src6:aria2ceed6:lengthi100e4:pathl19:aria2-0.2.2.tar.bz2eee4:name10:aria2-test12:piece lengthi128e6:pieces60:AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCee