2009-11-26 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

Fixed the bug which causes segmentation fault with tellWaiting
	XML-RPC method when BitTorrent download is waiting.  The key of
	BtRegistry is changed from info hash to GID, because it is
	registered per RequestGroup, not info hash.
	* src/BtRegistry.cc
	* src/BtRegistry.h
	* src/BtSetup.cc
	* src/ConsoleStatCalc.cc
	* src/InitiatorMSEHandshakeCommand.cc
	* src/PeerInitiateConnectionCommand.cc
	* src/PeerInteractionCommand.cc
	* src/PeerInteractionCommand.h
	* src/PeerReceiveHandshakeCommand.cc
	* src/RequestGroup.cc
	* src/XmlRpcMethodImpl.cc
	* test/BtRegistryTest.cc
	* test/XmlRpcMethodTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2009-11-25 15:49:20 +00:00
parent a26a44cb8e
commit 46d9f2de63
14 changed files with 133 additions and 88 deletions

View File

@ -1,3 +1,23 @@
2009-11-26 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed the bug which causes segmentation fault with tellWaiting
XML-RPC method when BitTorrent download is waiting. The key of
BtRegistry is changed from info hash to GID, because it is
registered per RequestGroup, not info hash.
* src/BtRegistry.cc
* src/BtRegistry.h
* src/BtSetup.cc
* src/ConsoleStatCalc.cc
* src/InitiatorMSEHandshakeCommand.cc
* src/PeerInitiateConnectionCommand.cc
* src/PeerInteractionCommand.cc
* src/PeerInteractionCommand.h
* src/PeerReceiveHandshakeCommand.cc
* src/RequestGroup.cc
* src/XmlRpcMethodImpl.cc
* test/BtRegistryTest.cc
* test/XmlRpcMethodTest.cc
2009-11-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> 2009-11-25 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Updated man page for changeOption XML-RPC method. Updated man page for changeOption XML-RPC method.

View File

@ -40,25 +40,40 @@
#include "BtAnnounce.h" #include "BtAnnounce.h"
#include "BtRuntime.h" #include "BtRuntime.h"
#include "BtProgressInfoFile.h" #include "BtProgressInfoFile.h"
#include "bittorrent_helper.h"
namespace aria2 { namespace aria2 {
SharedHandle<DownloadContext>
BtRegistry::getDownloadContext(int32_t gid) const
{
return get(gid)._downloadContext;
}
SharedHandle<DownloadContext> SharedHandle<DownloadContext>
BtRegistry::getDownloadContext(const std::string& infoHash) const BtRegistry::getDownloadContext(const std::string& infoHash) const
{ {
return get(infoHash)._downloadContext; SharedHandle<DownloadContext> dctx;
for(std::map<int32_t, BtObject>::const_iterator i = _pool.begin();
i != _pool.end(); ++i) {
const BDE& attrs =
(*i).second._downloadContext->getAttribute(bittorrent::BITTORRENT);
if(attrs[bittorrent::INFO_HASH].s() == infoHash) {
dctx = (*i).second._downloadContext;
break;
}
}
return dctx;
} }
void BtRegistry::put(const std::string& infoHash, const BtObject& obj) void BtRegistry::put(int32_t gid, const BtObject& obj)
{ {
remove(infoHash); _pool[gid] = obj;
std::map<std::string, BtObject>::value_type p(infoHash, obj);
_pool.insert(p);
} }
BtObject BtRegistry::get(const std::string& infoHash) const BtObject BtRegistry::get(int32_t gid) const
{ {
std::map<std::string, BtObject>::const_iterator i = _pool.find(infoHash); std::map<int32_t, BtObject>::const_iterator i = _pool.find(gid);
if(i == _pool.end()) { if(i == _pool.end()) {
return BtObject(); return BtObject();
} else { } else {
@ -66,9 +81,9 @@ BtObject BtRegistry::get(const std::string& infoHash) const
} }
} }
bool BtRegistry::remove(const std::string& infoHash) bool BtRegistry::remove(int32_t gid)
{ {
return _pool.erase(infoHash); return _pool.erase(gid);
} }
void BtRegistry::removeAll() { void BtRegistry::removeAll() {

View File

@ -37,7 +37,6 @@
#include "common.h" #include "common.h"
#include <string>
#include <map> #include <map>
#include "SharedHandle.h" #include "SharedHandle.h"
@ -87,19 +86,22 @@ struct BtObject {
class BtRegistry { class BtRegistry {
private: private:
std::map<std::string, BtObject> _pool; std::map<int32_t, BtObject> _pool;
public: public:
SharedHandle<DownloadContext>
getDownloadContext(int32_t gid) const;
SharedHandle<DownloadContext> SharedHandle<DownloadContext>
getDownloadContext(const std::string& infoHash) const; getDownloadContext(const std::string& infoHash) const;
void put(const std::string& infoHash, const BtObject& obj); void put(int32_t gid, const BtObject& obj);
BtObject get(const std::string& infoHash) const; BtObject get(int32_t gid) const;
template<typename OutputIterator> template<typename OutputIterator>
OutputIterator getAllDownloadContext(OutputIterator dest) OutputIterator getAllDownloadContext(OutputIterator dest)
{ {
for(std::map<std::string, BtObject>::const_iterator i = _pool.begin(); for(std::map<int32_t, BtObject>::const_iterator i = _pool.begin();
i != _pool.end(); ++i) { i != _pool.end(); ++i) {
*dest++ = (*i).second._downloadContext; *dest++ = (*i).second._downloadContext;
} }
@ -108,7 +110,7 @@ public:
void removeAll(); void removeAll();
bool remove(const std::string& infoHash); bool remove(int32_t gid);
}; };
} // namespace aria2 } // namespace aria2

View File

@ -76,8 +76,7 @@ void BtSetup::setup(std::deque<Command*>& commands,
const BDE& torrentAttrs = const BDE& torrentAttrs =
requestGroup->getDownloadContext()->getAttribute(bittorrent::BITTORRENT); requestGroup->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
bool metadataGetMode = !torrentAttrs.containsKey(bittorrent::METADATA); bool metadataGetMode = !torrentAttrs.containsKey(bittorrent::METADATA);
BtObject btObject = BtObject btObject = e->getBtRegistry()->get(requestGroup->getGID());
e->getBtRegistry()->get(torrentAttrs[bittorrent::INFO_HASH].s());
SharedHandle<PieceStorage> pieceStorage = btObject._pieceStorage; SharedHandle<PieceStorage> pieceStorage = btObject._pieceStorage;
SharedHandle<PeerStorage> peerStorage = btObject._peerStorage; SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
SharedHandle<BtRuntime> btRuntime = btObject._btRuntime; SharedHandle<BtRuntime> btRuntime = btObject._btRuntime;

View File

@ -116,10 +116,8 @@ static void printProgress
<< rg->getNumConnection(); << rg->getNumConnection();
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
if(rg->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) { if(rg->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
const BDE& torrentAttrs =
rg->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
SharedHandle<PeerStorage> ps = SharedHandle<PeerStorage> ps =
e->getBtRegistry()->get(torrentAttrs[bittorrent::INFO_HASH].s())._peerStorage; e->getBtRegistry()->get(rg->getGID())._peerStorage;
std::deque<SharedHandle<Peer> > peers; std::deque<SharedHandle<Peer> > peers;
ps->getActivePeers(peers); ps->getActivePeers(peers);
o << " " << "SEED:" o << " " << "SEED:"

View File

@ -152,11 +152,10 @@ bool InitiatorMSEHandshakeCommand::executeInternal() {
} }
PeerInteractionCommand* c = PeerInteractionCommand* c =
new PeerInteractionCommand new PeerInteractionCommand
(cuid, _requestGroup, peer, e, _btRuntime, _pieceStorage, (cuid, _requestGroup, peer, e, _btRuntime, _pieceStorage, _peerStorage,
socket, socket,
PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE,
peerConnection); peerConnection);
c->setPeerStorage(_peerStorage);
e->commands.push_back(c); e->commands.push_back(c);
return true; return true;
} }

View File

@ -89,9 +89,8 @@ bool PeerInitiateConnectionCommand::executeInternal() {
} else { } else {
PeerInteractionCommand* command = PeerInteractionCommand* command =
new PeerInteractionCommand new PeerInteractionCommand
(cuid, _requestGroup, peer, e, _btRuntime, _pieceStorage, (cuid, _requestGroup, peer, e, _btRuntime, _pieceStorage, _peerStorage,
socket, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE); socket, PeerInteractionCommand::INITIATOR_SEND_HANDSHAKE);
command->setPeerStorage(_peerStorage);
e->commands.push_back(command); e->commands.push_back(command);
} }
return true; return true;

View File

@ -45,7 +45,6 @@
#include "Socket.h" #include "Socket.h"
#include "Option.h" #include "Option.h"
#include "DownloadContext.h" #include "DownloadContext.h"
#include "BtRegistry.h"
#include "Peer.h" #include "Peer.h"
#include "BtMessage.h" #include "BtMessage.h"
#include "BtRuntime.h" #include "BtRuntime.h"
@ -83,6 +82,7 @@ PeerInteractionCommand::PeerInteractionCommand
DownloadEngine* e, DownloadEngine* e,
const SharedHandle<BtRuntime>& btRuntime, const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<PieceStorage>& pieceStorage, const SharedHandle<PieceStorage>& pieceStorage,
const SharedHandle<PeerStorage>& peerStorage,
const SocketHandle& s, const SocketHandle& s,
Seq sequence, Seq sequence,
const PeerConnectionHandle& passedPeerConnection) const PeerConnectionHandle& passedPeerConnection)
@ -90,6 +90,7 @@ PeerInteractionCommand::PeerInteractionCommand
_requestGroup(requestGroup), _requestGroup(requestGroup),
_btRuntime(btRuntime), _btRuntime(btRuntime),
_pieceStorage(pieceStorage), _pieceStorage(pieceStorage),
_peerStorage(peerStorage),
sequence(sequence) sequence(sequence)
{ {
// TODO move following bunch of processing to separate method, like init() // TODO move following bunch of processing to separate method, like init()
@ -101,9 +102,6 @@ PeerInteractionCommand::PeerInteractionCommand
const BDE& torrentAttrs = const BDE& torrentAttrs =
_requestGroup->getDownloadContext()->getAttribute(bittorrent::BITTORRENT); _requestGroup->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
SharedHandle<BtRegistry> btRegistry = e->getBtRegistry();
SharedHandle<PeerStorage> peerStorage =
btRegistry->get(torrentAttrs[bittorrent::INFO_HASH].s())._peerStorage;
bool metadataGetMode = !torrentAttrs.containsKey(bittorrent::METADATA); bool metadataGetMode = !torrentAttrs.containsKey(bittorrent::METADATA);
@ -354,12 +352,6 @@ bool PeerInteractionCommand::exitBeforeExecute()
return _btRuntime->isHalt(); return _btRuntime->isHalt();
} }
void PeerInteractionCommand::setPeerStorage
(const SharedHandle<PeerStorage>& peerStorage)
{
_peerStorage = peerStorage;
}
const SharedHandle<Option>& PeerInteractionCommand::getOption() const const SharedHandle<Option>& PeerInteractionCommand::getOption() const
{ {
return _requestGroup->getOption(); return _requestGroup->getOption();

View File

@ -80,14 +80,13 @@ public:
DownloadEngine* e, DownloadEngine* e,
const SharedHandle<BtRuntime>& btRuntime, const SharedHandle<BtRuntime>& btRuntime,
const SharedHandle<PieceStorage>& pieceStorage, const SharedHandle<PieceStorage>& pieceStorage,
const SharedHandle<PeerStorage>& peerStorage,
const SharedHandle<SocketCore>& s, const SharedHandle<SocketCore>& s,
Seq sequence, Seq sequence,
const SharedHandle<PeerConnection>& peerConnection = const SharedHandle<PeerConnection>& peerConnection =
SharedHandle<PeerConnection>()); SharedHandle<PeerConnection>());
virtual ~PeerInteractionCommand(); virtual ~PeerInteractionCommand();
void setPeerStorage(const SharedHandle<PeerStorage>& peerStorage);
}; };
} // namespace aria2 } // namespace aria2

View File

@ -93,17 +93,24 @@ bool PeerReceiveHandshakeCommand::executeInternal()
// check info_hash // check info_hash
std::string infoHash = std::string(&data[28], &data[28+INFO_HASH_LENGTH]); std::string infoHash = std::string(&data[28], &data[28+INFO_HASH_LENGTH]);
BtObject btObject = e->getBtRegistry()->get(infoHash); SharedHandle<DownloadContext> downloadContext =
SharedHandle<DownloadContext> downloadContext = btObject._downloadContext; e->getBtRegistry()->getDownloadContext(infoHash);
SharedHandle<BtRuntime> btRuntime = btObject._btRuntime; if(downloadContext.isNull()) {
SharedHandle<PieceStorage> pieceStorage = btObject._pieceStorage;
SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
if(downloadContext.isNull() || !btRuntime->ready()) {
throw DL_ABORT_EX throw DL_ABORT_EX
(StringFormat("Unknown info hash %s", (StringFormat("Unknown info hash %s",
util::toHex(infoHash).c_str()).str()); util::toHex(infoHash).c_str()).str());
} }
BtObject btObject = e->getBtRegistry()->get
(downloadContext->getOwnerRequestGroup()->getGID());
SharedHandle<BtRuntime> btRuntime = btObject._btRuntime;
SharedHandle<PieceStorage> pieceStorage = btObject._pieceStorage;
SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
if(!btRuntime->ready()) {
throw DL_ABORT_EX
(StringFormat("Unknown info hash %s",
util::toHex(infoHash).c_str()).str());
}
TransferStat tstat = TransferStat tstat =
downloadContext->getOwnerRequestGroup()->calculateStat(); downloadContext->getOwnerRequestGroup()->calculateStat();
const unsigned int maxDownloadLimit = const unsigned int maxDownloadLimit =
@ -130,10 +137,10 @@ bool PeerReceiveHandshakeCommand::executeInternal()
e, e,
btRuntime, btRuntime,
pieceStorage, pieceStorage,
peerStorage,
socket, socket,
PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE, PeerInteractionCommand::RECEIVER_WAIT_HANDSHAKE,
_peerConnection); _peerConnection);
command->setPeerStorage(peerStorage);
e->commands.push_back(command); e->commands.push_back(command);
logger->debug(MSG_INCOMING_PEER_CONNECTION, cuid, peer->usedBy()); logger->debug(MSG_INCOMING_PEER_CONNECTION, cuid, peer->usedBy());
} }

View File

@ -264,7 +264,7 @@ void RequestGroup::createInitialCommand
(_option->getAsInt(PREF_BT_TRACKER_INTERVAL)); (_option->getAsInt(PREF_BT_TRACKER_INTERVAL));
btAnnounce->shuffleAnnounce(); btAnnounce->shuffleAnnounce();
btRegistry->put(torrentAttrs[bittorrent::INFO_HASH].s(), btRegistry->put(_gid,
BtObject(_downloadContext, BtObject(_downloadContext,
_pieceStorage, _pieceStorage,
peerStorage, peerStorage,
@ -774,22 +774,7 @@ void RequestGroup::releaseRuntimeResource(DownloadEngine* e)
{ {
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
if(_downloadContext->hasAttribute(bittorrent::BITTORRENT)) { if(_downloadContext->hasAttribute(bittorrent::BITTORRENT)) {
SharedHandle<BtRegistry> btRegistry = e->getBtRegistry(); e->getBtRegistry()->remove(_gid);
const BDE& torrentAttrs =
_downloadContext->getAttribute(bittorrent::BITTORRENT);
const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s();
SharedHandle<DownloadContext> contextInReg =
btRegistry->getDownloadContext(infoHash);
// Make sure that the registered DownloadContext's GID is equal to
// _gid. Even if createInitialCommand() throws exception without
// registering this DownloadContext, after that, this method is
// called. In this case, just finding DownloadContext using
// infoHash may detect another download's DownloadContext and
// deleting it from BtRegistry causes Segmentation Fault.
if(!contextInReg.isNull() &&
contextInReg->getOwnerRequestGroup()->getGID() == _gid) {
btRegistry->remove(infoHash);
}
} }
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
if(!_pieceStorage.isNull()) { if(!_pieceStorage.isNull()) {

View File

@ -290,17 +290,19 @@ static void gatherProgressCommon
#ifdef ENABLE_BITTORRENT #ifdef ENABLE_BITTORRENT
static void gatherProgressBitTorrent static void gatherProgressBitTorrent
(BDE& entryDict, const BDE& torrentAttrs, const SharedHandle<BtRegistry>& btreg) (BDE& entryDict, const BDE& torrentAttrs, const BtObject& btObject)
{ {
const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s(); const std::string& infoHash = torrentAttrs[bittorrent::INFO_HASH].s();
entryDict["infoHash"] = util::toHex(infoHash); entryDict["infoHash"] = util::toHex(infoHash);
SharedHandle<PeerStorage> peerStorage = btreg->get(infoHash)._peerStorage; if(!btObject.isNull()) {
assert(!peerStorage.isNull()); SharedHandle<PeerStorage> peerStorage = btObject._peerStorage;
assert(!peerStorage.isNull());
std::deque<SharedHandle<Peer> > peers; std::deque<SharedHandle<Peer> > peers;
peerStorage->getActivePeers(peers); peerStorage->getActivePeers(peers);
entryDict["numSeeders"] = countSeeder(peers.begin(), peers.end()); entryDict["numSeeders"] = countSeeder(peers.begin(), peers.end());
}
} }
static void gatherPeer(BDE& peers, const SharedHandle<PeerStorage>& ps) static void gatherPeer(BDE& peers, const SharedHandle<PeerStorage>& ps)
@ -335,8 +337,8 @@ static void gatherProgress
if(group->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) { if(group->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
const BDE& torrentAttrs = const BDE& torrentAttrs =
group->getDownloadContext()->getAttribute(bittorrent::BITTORRENT); group->getDownloadContext()->getAttribute(bittorrent::BITTORRENT);
SharedHandle<BtRegistry> btreg = e->getBtRegistry(); BtObject btObject = e->getBtRegistry()->get(group->getGID());
gatherProgressBitTorrent(entryDict, torrentAttrs, btreg); gatherProgressBitTorrent(entryDict, torrentAttrs, btObject);
} }
#endif // ENABLE_BITTORRENT #endif // ENABLE_BITTORRENT
} }
@ -463,14 +465,11 @@ BDE GetPeersXmlRpcMethod::process
} }
BDE peers = BDE::list(); BDE peers = BDE::list();
if(group->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) { if(group->getDownloadContext()->hasAttribute(bittorrent::BITTORRENT)) {
SharedHandle<BtRegistry> btreg = e->getBtRegistry(); BtObject btObject = e->getBtRegistry()->get(group->getGID());
const BDE& torrentAttrs = if(!btObject.isNull()) {
group->getDownloadContext()->getAttribute(bittorrent::BITTORRENT); assert(!btObject._peerStorage.isNull());
SharedHandle<PeerStorage> peerStorage = gatherPeer(peers, btObject._peerStorage);
btreg->get(torrentAttrs[bittorrent::INFO_HASH].s())._peerStorage; }
assert(!peerStorage.isNull());
BDE entry = BDE::dict();
gatherPeer(peers, peerStorage);
} }
return peers; return peers;
} }

View File

@ -10,6 +10,7 @@
#include "MockBtProgressInfoFile.h" #include "MockBtProgressInfoFile.h"
#include "BtRuntime.h" #include "BtRuntime.h"
#include "FileEntry.h" #include "FileEntry.h"
#include "bittorrent_helper.h"
namespace aria2 { namespace aria2 {
@ -17,6 +18,7 @@ class BtRegistryTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(BtRegistryTest); CPPUNIT_TEST_SUITE(BtRegistryTest);
CPPUNIT_TEST(testGetDownloadContext); CPPUNIT_TEST(testGetDownloadContext);
CPPUNIT_TEST(testGetDownloadContext_infoHash);
CPPUNIT_TEST(testGetAllDownloadContext); CPPUNIT_TEST(testGetAllDownloadContext);
CPPUNIT_TEST(testRemove); CPPUNIT_TEST(testRemove);
CPPUNIT_TEST(testRemoveAll); CPPUNIT_TEST(testRemoveAll);
@ -25,6 +27,7 @@ private:
public: public:
void testGetDownloadContext(); void testGetDownloadContext();
void testGetDownloadContext_infoHash();
void testGetAllDownloadContext(); void testGetAllDownloadContext();
void testRemove(); void testRemove();
void testRemoveAll(); void testRemoveAll();
@ -36,12 +39,12 @@ CPPUNIT_TEST_SUITE_REGISTRATION( BtRegistryTest );
void BtRegistryTest::testGetDownloadContext() void BtRegistryTest::testGetDownloadContext()
{ {
BtRegistry btRegistry; BtRegistry btRegistry;
CPPUNIT_ASSERT(btRegistry.getDownloadContext("test").isNull()); CPPUNIT_ASSERT(btRegistry.getDownloadContext(1).isNull());
SharedHandle<DownloadContext> dctx(new DownloadContext()); SharedHandle<DownloadContext> dctx(new DownloadContext());
BtObject btObject; BtObject btObject;
btObject._downloadContext = dctx; btObject._downloadContext = dctx;
btRegistry.put("test", btObject); btRegistry.put(1, btObject);
CPPUNIT_ASSERT_EQUAL(dctx.get(), btRegistry.getDownloadContext("test").get()); CPPUNIT_ASSERT_EQUAL(dctx.get(), btRegistry.getDownloadContext(1).get());
} }
static void addTwoDownloadContext(BtRegistry& btRegistry) static void addTwoDownloadContext(BtRegistry& btRegistry)
@ -52,8 +55,27 @@ static void addTwoDownloadContext(BtRegistry& btRegistry)
btObject1._downloadContext = dctx1; btObject1._downloadContext = dctx1;
BtObject btObject2; BtObject btObject2;
btObject2._downloadContext = dctx2; btObject2._downloadContext = dctx2;
btRegistry.put("ctx1", btObject1); btRegistry.put(1, btObject1);
btRegistry.put("ctx2", btObject2); btRegistry.put(2, btObject2);
}
void BtRegistryTest::testGetDownloadContext_infoHash()
{
BtRegistry btRegistry;
addTwoDownloadContext(btRegistry);
BDE attrs1 = BDE::dict();
attrs1[bittorrent::INFO_HASH] = std::string("hash1");
BDE attrs2 = BDE::dict();
attrs2[bittorrent::INFO_HASH] = std::string("hash2");
btRegistry.getDownloadContext(1)->setAttribute
(bittorrent::BITTORRENT, attrs1);
btRegistry.getDownloadContext(2)->setAttribute
(bittorrent::BITTORRENT, attrs2);
CPPUNIT_ASSERT(!btRegistry.getDownloadContext("hash1").isNull());
CPPUNIT_ASSERT(btRegistry.getDownloadContext("hash1").get() ==
btRegistry.getDownloadContext(1).get());
CPPUNIT_ASSERT(btRegistry.getDownloadContext("not exists").isNull());
} }
void BtRegistryTest::testGetAllDownloadContext() void BtRegistryTest::testGetAllDownloadContext()
@ -70,9 +92,9 @@ void BtRegistryTest::testRemove()
{ {
BtRegistry btRegistry; BtRegistry btRegistry;
addTwoDownloadContext(btRegistry); addTwoDownloadContext(btRegistry);
CPPUNIT_ASSERT(btRegistry.remove("ctx1")); CPPUNIT_ASSERT(btRegistry.remove(1));
CPPUNIT_ASSERT(btRegistry.get("ctx1").isNull()); CPPUNIT_ASSERT(btRegistry.get(1).isNull());
CPPUNIT_ASSERT(!btRegistry.get("ctx2").isNull()); CPPUNIT_ASSERT(!btRegistry.get(2).isNull());
} }
void BtRegistryTest::testRemoveAll() void BtRegistryTest::testRemoveAll()
@ -80,8 +102,8 @@ void BtRegistryTest::testRemoveAll()
BtRegistry btRegistry; BtRegistry btRegistry;
addTwoDownloadContext(btRegistry); addTwoDownloadContext(btRegistry);
btRegistry.removeAll(); btRegistry.removeAll();
CPPUNIT_ASSERT(btRegistry.get("ctx1").isNull()); CPPUNIT_ASSERT(btRegistry.get(1).isNull());
CPPUNIT_ASSERT(btRegistry.get("ctx2").isNull()); CPPUNIT_ASSERT(btRegistry.get(2).isNull());
} }
} // namespace aria2 } // namespace aria2

View File

@ -515,12 +515,21 @@ static void addUri(const std::string& uri,
CPPUNIT_ASSERT_EQUAL(0, m.execute(req, e.get())._code); CPPUNIT_ASSERT_EQUAL(0, m.execute(req, e.get())._code);
} }
static void addTorrent
(const std::string& torrentFile, const SharedHandle<DownloadEngine>& e)
{
AddTorrentXmlRpcMethod m;
XmlRpcRequest req("aria2.addTorrent", BDE::list());
req._params << BDE(readFile(torrentFile));
XmlRpcResponse res = m.execute(req, e.get());
}
void XmlRpcMethodTest::testTellWaiting() void XmlRpcMethodTest::testTellWaiting()
{ {
addUri("http://1/", _e); addUri("http://1/", _e);
addUri("http://2/", _e); addUri("http://2/", _e);
addUri("http://3/", _e); addUri("http://3/", _e);
addUri("http://4/", _e); addTorrent("single.torrent", _e);
TellWaitingXmlRpcMethod m; TellWaitingXmlRpcMethod m;
XmlRpcRequest req("aria2.tellWaiting", BDE::list()); XmlRpcRequest req("aria2.tellWaiting", BDE::list());