RpcMethodTest.cc 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421
  1. #include "RpcMethod.h"
  2. #include <cppunit/extensions/HelperMacros.h>
  3. #include "DownloadEngine.h"
  4. #include "SelectEventPoll.h"
  5. #include "Option.h"
  6. #include "RequestGroupMan.h"
  7. #include "RequestGroup.h"
  8. #include "RpcMethodImpl.h"
  9. #include "OptionParser.h"
  10. #include "OptionHandler.h"
  11. #include "RpcRequest.h"
  12. #include "RpcResponse.h"
  13. #include "prefs.h"
  14. #include "TestUtil.h"
  15. #include "DownloadContext.h"
  16. #include "FeatureConfig.h"
  17. #include "util.h"
  18. #include "array_fun.h"
  19. #include "download_helper.h"
  20. #include "FileEntry.h"
  21. #include "RpcMethodFactory.h"
  22. #ifdef ENABLE_BITTORRENT
  23. #include "BtRegistry.h"
  24. #include "BtRuntime.h"
  25. #include "bittorrent_helper.h"
  26. #endif // ENABLE_BITTORRENT
  27. namespace aria2 {
  28. namespace rpc {
  29. class RpcMethodTest : public CppUnit::TestFixture {
  30. CPPUNIT_TEST_SUITE(RpcMethodTest);
  31. CPPUNIT_TEST(testAuthorize);
  32. CPPUNIT_TEST(testAddUri);
  33. CPPUNIT_TEST(testAddUri_withoutUri);
  34. CPPUNIT_TEST(testAddUri_notUri);
  35. CPPUNIT_TEST(testAddUri_withBadOption);
  36. CPPUNIT_TEST(testAddUri_withPosition);
  37. CPPUNIT_TEST(testAddUri_withBadPosition);
  38. #ifdef ENABLE_BITTORRENT
  39. CPPUNIT_TEST(testAddTorrent);
  40. CPPUNIT_TEST(testAddTorrent_withoutTorrent);
  41. CPPUNIT_TEST(testAddTorrent_notBase64Torrent);
  42. CPPUNIT_TEST(testAddTorrent_withPosition);
  43. #endif // ENABLE_BITTORRENT
  44. #ifdef ENABLE_METALINK
  45. CPPUNIT_TEST(testAddMetalink);
  46. CPPUNIT_TEST(testAddMetalink_withoutMetalink);
  47. CPPUNIT_TEST(testAddMetalink_notBase64Metalink);
  48. CPPUNIT_TEST(testAddMetalink_withPosition);
  49. #endif // ENABLE_METALINK
  50. CPPUNIT_TEST(testGetOption);
  51. CPPUNIT_TEST(testChangeOption);
  52. CPPUNIT_TEST(testChangeOption_withBadOption);
  53. CPPUNIT_TEST(testChangeOption_withNotAllowedOption);
  54. CPPUNIT_TEST(testChangeOption_withoutGid);
  55. CPPUNIT_TEST(testChangeGlobalOption);
  56. CPPUNIT_TEST(testChangeGlobalOption_withBadOption);
  57. CPPUNIT_TEST(testChangeGlobalOption_withNotAllowedOption);
  58. CPPUNIT_TEST(testTellStatus_withoutGid);
  59. CPPUNIT_TEST(testTellWaiting);
  60. CPPUNIT_TEST(testTellWaiting_fail);
  61. CPPUNIT_TEST(testGetVersion);
  62. CPPUNIT_TEST(testNoSuchMethod);
  63. CPPUNIT_TEST(testGatherStoppedDownload);
  64. CPPUNIT_TEST(testGatherProgressCommon);
  65. #ifdef ENABLE_BITTORRENT
  66. CPPUNIT_TEST(testGatherBitTorrentMetadata);
  67. #endif // ENABLE_BITTORRENT
  68. CPPUNIT_TEST(testChangePosition);
  69. CPPUNIT_TEST(testChangePosition_fail);
  70. CPPUNIT_TEST(testGetSessionInfo);
  71. CPPUNIT_TEST(testChangeUri);
  72. CPPUNIT_TEST(testChangeUri_fail);
  73. CPPUNIT_TEST(testPause);
  74. CPPUNIT_TEST(testSystemMulticall);
  75. CPPUNIT_TEST(testSystemMulticall_fail);
  76. CPPUNIT_TEST(testSystemListMethods);
  77. CPPUNIT_TEST(testSystemListNotifications);
  78. CPPUNIT_TEST_SUITE_END();
  79. private:
  80. std::shared_ptr<DownloadEngine> e_;
  81. std::shared_ptr<Option> option_;
  82. public:
  83. void setUp()
  84. {
  85. option_ = std::make_shared<Option>();
  86. option_->put(PREF_DIR, A2_TEST_OUT_DIR "/aria2_RpcMethodTest");
  87. option_->put(PREF_PIECE_LENGTH, "1048576");
  88. option_->put(PREF_MAX_DOWNLOAD_RESULT, "10");
  89. File(option_->get(PREF_DIR)).mkdirs();
  90. e_ = make_unique<DownloadEngine>(make_unique<SelectEventPoll>());
  91. e_->setOption(option_.get());
  92. e_->setRequestGroupMan(make_unique<RequestGroupMan>(
  93. std::vector<std::shared_ptr<RequestGroup>>{}, 1, option_.get()));
  94. }
  95. void testAuthorize();
  96. void testAddUri();
  97. void testAddUri_withoutUri();
  98. void testAddUri_notUri();
  99. void testAddUri_withBadOption();
  100. void testAddUri_withPosition();
  101. void testAddUri_withBadPosition();
  102. #ifdef ENABLE_BITTORRENT
  103. void testAddTorrent();
  104. void testAddTorrent_withoutTorrent();
  105. void testAddTorrent_notBase64Torrent();
  106. void testAddTorrent_withPosition();
  107. #endif // ENABLE_BITTORRENT
  108. #ifdef ENABLE_METALINK
  109. void testAddMetalink();
  110. void testAddMetalink_withoutMetalink();
  111. void testAddMetalink_notBase64Metalink();
  112. void testAddMetalink_withPosition();
  113. #endif // ENABLE_METALINK
  114. void testGetOption();
  115. void testChangeOption();
  116. void testChangeOption_withBadOption();
  117. void testChangeOption_withNotAllowedOption();
  118. void testChangeOption_withoutGid();
  119. void testChangeGlobalOption();
  120. void testChangeGlobalOption_withBadOption();
  121. void testChangeGlobalOption_withNotAllowedOption();
  122. void testTellStatus_withoutGid();
  123. void testTellWaiting();
  124. void testTellWaiting_fail();
  125. void testGetVersion();
  126. void testNoSuchMethod();
  127. void testGatherStoppedDownload();
  128. void testGatherProgressCommon();
  129. #ifdef ENABLE_BITTORRENT
  130. void testGatherBitTorrentMetadata();
  131. #endif // ENABLE_BITTORRENT
  132. void testChangePosition();
  133. void testChangePosition_fail();
  134. void testGetSessionInfo();
  135. void testChangeUri();
  136. void testChangeUri_fail();
  137. void testPause();
  138. void testSystemMulticall();
  139. void testSystemMulticall_fail();
  140. void testSystemListMethods();
  141. void testSystemListNotifications();
  142. };
  143. CPPUNIT_TEST_SUITE_REGISTRATION(RpcMethodTest);
  144. namespace {
  145. std::string getString(const Dict* dict, const std::string& key)
  146. {
  147. return downcast<String>(dict->get(key))->s();
  148. }
  149. } // namespace
  150. namespace {
  151. RpcRequest createReq(std::string methodName)
  152. {
  153. return {std::move(methodName), List::g()};
  154. }
  155. } // namespace
  156. void RpcMethodTest::testAuthorize()
  157. {
  158. // Select RPC method which takes non-string parameter to make sure
  159. // that token: prefixed parameter is stripped before the call.
  160. TellActiveRpcMethod m;
  161. // no secret token set and no token: prefixed parameter is given
  162. {
  163. auto req = createReq(TellActiveRpcMethod::getMethodName());
  164. auto res = m.execute(std::move(req), e_.get());
  165. CPPUNIT_ASSERT_EQUAL(0, res.code);
  166. }
  167. // no secret token set and token: prefixed parameter is given
  168. {
  169. auto req = createReq(GetVersionRpcMethod::getMethodName());
  170. req.params->append("token:foo");
  171. auto res = m.execute(std::move(req), e_.get());
  172. CPPUNIT_ASSERT_EQUAL(0, res.code);
  173. }
  174. e_->getOption()->put(PREF_RPC_SECRET, "foo");
  175. // secret token set and no token: prefixed parameter is given
  176. {
  177. auto req = createReq(GetVersionRpcMethod::getMethodName());
  178. auto res = m.execute(std::move(req), e_.get());
  179. CPPUNIT_ASSERT_EQUAL(1, res.code);
  180. }
  181. // secret token set and token: prefixed parameter is given
  182. {
  183. auto req = createReq(GetVersionRpcMethod::getMethodName());
  184. req.params->append("token:foo");
  185. auto res = m.execute(std::move(req), e_.get());
  186. CPPUNIT_ASSERT_EQUAL(0, res.code);
  187. }
  188. // secret token set and bad token: prefixed parameter is given
  189. {
  190. auto req = createReq(GetVersionRpcMethod::getMethodName());
  191. req.params->append("token:foo2");
  192. auto res = m.execute(std::move(req), e_.get());
  193. CPPUNIT_ASSERT_EQUAL(1, res.code);
  194. }
  195. }
  196. void RpcMethodTest::testAddUri()
  197. {
  198. AddUriRpcMethod m;
  199. {
  200. auto req = createReq(AddUriRpcMethod::getMethodName());
  201. auto urisParam = List::g();
  202. urisParam->append("http://localhost/");
  203. req.params->append(std::move(urisParam));
  204. auto res = m.execute(std::move(req), e_.get());
  205. CPPUNIT_ASSERT_EQUAL(0, res.code);
  206. const RequestGroupList& rgs = e_->getRequestGroupMan()->getReservedGroups();
  207. CPPUNIT_ASSERT_EQUAL((size_t)1, rgs.size());
  208. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/"),
  209. (*rgs.begin())
  210. ->getDownloadContext()
  211. ->getFirstFileEntry()
  212. ->getRemainingUris()
  213. .front());
  214. }
  215. {
  216. auto req = createReq(AddUriRpcMethod::getMethodName());
  217. auto urisParam = List::g();
  218. urisParam->append("http://localhost/");
  219. req.params->append(std::move(urisParam));
  220. // with options
  221. auto opt = Dict::g();
  222. opt->put(PREF_DIR->k, "/sink");
  223. req.params->append(std::move(opt));
  224. auto res = m.execute(std::move(req), e_.get());
  225. CPPUNIT_ASSERT_EQUAL(0, res.code);
  226. a2_gid_t gid;
  227. CPPUNIT_ASSERT_EQUAL(
  228. 0, GroupId::toNumericId(gid, downcast<String>(res.param)->s().c_str()));
  229. CPPUNIT_ASSERT_EQUAL(std::string("/sink"),
  230. findReservedGroup(e_->getRequestGroupMan().get(), gid)
  231. ->getOption()
  232. ->get(PREF_DIR));
  233. }
  234. }
  235. void RpcMethodTest::testAddUri_withoutUri()
  236. {
  237. AddUriRpcMethod m;
  238. auto res = m.execute(createReq(AddUriRpcMethod::getMethodName()), e_.get());
  239. CPPUNIT_ASSERT_EQUAL(1, res.code);
  240. }
  241. void RpcMethodTest::testAddUri_notUri()
  242. {
  243. AddUriRpcMethod m;
  244. auto req = createReq(AddUriRpcMethod::getMethodName());
  245. auto urisParam = List::g();
  246. urisParam->append("not uri");
  247. req.params->append(std::move(urisParam));
  248. auto res = m.execute(std::move(req), e_.get());
  249. CPPUNIT_ASSERT_EQUAL(1, res.code);
  250. }
  251. void RpcMethodTest::testAddUri_withBadOption()
  252. {
  253. AddUriRpcMethod m;
  254. auto req = createReq(AddUriRpcMethod::getMethodName());
  255. auto urisParam = List::g();
  256. urisParam->append("http://localhost");
  257. req.params->append(std::move(urisParam));
  258. auto opt = Dict::g();
  259. opt->put(PREF_FILE_ALLOCATION->k, "badvalue");
  260. req.params->append(std::move(opt));
  261. auto res = m.execute(std::move(req), e_.get());
  262. CPPUNIT_ASSERT_EQUAL(1, res.code);
  263. }
  264. void RpcMethodTest::testAddUri_withPosition()
  265. {
  266. AddUriRpcMethod m;
  267. auto req1 = createReq(AddUriRpcMethod::getMethodName());
  268. auto urisParam1 = List::g();
  269. urisParam1->append("http://uri1");
  270. req1.params->append(std::move(urisParam1));
  271. auto res1 = m.execute(std::move(req1), e_.get());
  272. CPPUNIT_ASSERT_EQUAL(0, res1.code);
  273. auto req2 = createReq(AddUriRpcMethod::getMethodName());
  274. auto urisParam2 = List::g();
  275. urisParam2->append("http://uri2");
  276. req2.params->append(std::move(urisParam2));
  277. req2.params->append(Dict::g());
  278. req2.params->append(Integer::g(0));
  279. m.execute(std::move(req2), e_.get());
  280. std::string uri = getReservedGroup(e_->getRequestGroupMan().get(), 0)
  281. ->getDownloadContext()
  282. ->getFirstFileEntry()
  283. ->getRemainingUris()[0];
  284. CPPUNIT_ASSERT_EQUAL(std::string("http://uri2"), uri);
  285. }
  286. void RpcMethodTest::testAddUri_withBadPosition()
  287. {
  288. AddUriRpcMethod m;
  289. auto req = createReq(AddUriRpcMethod::getMethodName());
  290. auto urisParam = List::g();
  291. urisParam->append("http://localhost/");
  292. req.params->append(std::move(urisParam));
  293. req.params->append(Dict::g());
  294. req.params->append(Integer::g(-1));
  295. auto res = m.execute(std::move(req), e_.get());
  296. CPPUNIT_ASSERT_EQUAL(1, res.code);
  297. }
  298. #ifdef ENABLE_BITTORRENT
  299. namespace {
  300. RpcRequest createAddTorrentReq()
  301. {
  302. auto req = createReq(AddTorrentRpcMethod::getMethodName());
  303. req.params->append(readFile(A2_TEST_DIR "/single.torrent"));
  304. auto uris = List::g();
  305. uris->append("http://localhost/aria2-0.8.2.tar.bz2");
  306. req.params->append(std::move(uris));
  307. return req;
  308. }
  309. } // namespace
  310. void RpcMethodTest::testAddTorrent()
  311. {
  312. File(e_->getOption()->get(PREF_DIR) +
  313. "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").remove();
  314. AddTorrentRpcMethod m;
  315. {
  316. // Saving upload metadata is disabled by option.
  317. auto res = m.execute(createAddTorrentReq(), e_.get());
  318. CPPUNIT_ASSERT(
  319. !File(e_->getOption()->get(PREF_DIR) +
  320. "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").exists());
  321. CPPUNIT_ASSERT_EQUAL(0, res.code);
  322. CPPUNIT_ASSERT_EQUAL(sizeof(a2_gid_t) * 2,
  323. downcast<String>(res.param)->s().size());
  324. }
  325. e_->getOption()->put(PREF_RPC_SAVE_UPLOAD_METADATA, A2_V_TRUE);
  326. {
  327. auto res = m.execute(createAddTorrentReq(), e_.get());
  328. CPPUNIT_ASSERT(
  329. File(e_->getOption()->get(PREF_DIR) +
  330. "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").exists());
  331. CPPUNIT_ASSERT_EQUAL(0, res.code);
  332. a2_gid_t gid;
  333. CPPUNIT_ASSERT_EQUAL(
  334. 0, GroupId::toNumericId(gid, downcast<String>(res.param)->s().c_str()));
  335. auto group = findReservedGroup(e_->getRequestGroupMan().get(), gid);
  336. CPPUNIT_ASSERT(group);
  337. CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR) +
  338. "/aria2-0.8.2.tar.bz2",
  339. group->getFirstFilePath());
  340. CPPUNIT_ASSERT_EQUAL((size_t)1, group->getDownloadContext()
  341. ->getFirstFileEntry()
  342. ->getRemainingUris()
  343. .size());
  344. CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/aria2-0.8.2.tar.bz2"),
  345. group->getDownloadContext()
  346. ->getFirstFileEntry()
  347. ->getRemainingUris()[0]);
  348. }
  349. {
  350. auto req = createAddTorrentReq();
  351. // with options
  352. std::string dir = A2_TEST_OUT_DIR "/aria2_RpcMethodTest_testAddTorrent";
  353. File(dir).mkdirs();
  354. auto opt = Dict::g();
  355. opt->put(PREF_DIR->k, dir);
  356. File(dir + "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent").remove();
  357. req.params->append(std::move(opt));
  358. auto res = m.execute(std::move(req), e_.get());
  359. CPPUNIT_ASSERT_EQUAL(0, res.code);
  360. a2_gid_t gid;
  361. CPPUNIT_ASSERT_EQUAL(
  362. 0, GroupId::toNumericId(gid, downcast<String>(res.param)->s().c_str()));
  363. CPPUNIT_ASSERT_EQUAL(dir + "/aria2-0.8.2.tar.bz2",
  364. findReservedGroup(e_->getRequestGroupMan().get(), gid)
  365. ->getFirstFilePath());
  366. CPPUNIT_ASSERT(
  367. File(dir + "/0a3893293e27ac0490424c06de4d09242215f0a6.torrent")
  368. .exists());
  369. }
  370. }
  371. void RpcMethodTest::testAddTorrent_withoutTorrent()
  372. {
  373. AddTorrentRpcMethod m;
  374. auto res =
  375. m.execute(createReq(AddTorrentRpcMethod::getMethodName()), e_.get());
  376. CPPUNIT_ASSERT_EQUAL(1, res.code);
  377. }
  378. void RpcMethodTest::testAddTorrent_notBase64Torrent()
  379. {
  380. AddTorrentRpcMethod m;
  381. auto req = createReq(AddTorrentRpcMethod::getMethodName());
  382. req.params->append("not torrent");
  383. auto res = m.execute(std::move(req), e_.get());
  384. CPPUNIT_ASSERT_EQUAL(1, res.code);
  385. }
  386. void RpcMethodTest::testAddTorrent_withPosition()
  387. {
  388. AddTorrentRpcMethod m;
  389. auto req1 = createReq(AddTorrentRpcMethod::getMethodName());
  390. req1.params->append(readFile(A2_TEST_DIR "/test.torrent"));
  391. req1.params->append(List::g());
  392. req1.params->append(Dict::g());
  393. auto res1 = m.execute(std::move(req1), e_.get());
  394. CPPUNIT_ASSERT_EQUAL(0, res1.code);
  395. auto req2 = createReq(AddTorrentRpcMethod::getMethodName());
  396. req2.params->append(readFile(A2_TEST_DIR "/single.torrent"));
  397. req2.params->append(List::g());
  398. req2.params->append(Dict::g());
  399. req2.params->append(Integer::g(0));
  400. m.execute(std::move(req2), e_.get());
  401. CPPUNIT_ASSERT_EQUAL((size_t)1,
  402. getReservedGroup(e_->getRequestGroupMan().get(), 0)
  403. ->getDownloadContext()
  404. ->getFileEntries()
  405. .size());
  406. }
  407. #endif // ENABLE_BITTORRENT
  408. #ifdef ENABLE_METALINK
  409. namespace {
  410. RpcRequest createAddMetalinkReq()
  411. {
  412. auto req = createReq(AddMetalinkRpcMethod::getMethodName());
  413. req.params->append(readFile(A2_TEST_DIR "/2files.metalink"));
  414. return req;
  415. }
  416. } // namespace
  417. void RpcMethodTest::testAddMetalink()
  418. {
  419. File(e_->getOption()->get(PREF_DIR) +
  420. "/c908634fbc257fd56f0114912c2772aeeb4064f4.meta4").remove();
  421. AddMetalinkRpcMethod m;
  422. {
  423. // Saving upload metadata is disabled by option.
  424. auto res = m.execute(createAddMetalinkReq(), e_.get());
  425. CPPUNIT_ASSERT_EQUAL(0, res.code);
  426. const List* resParams = downcast<List>(res.param);
  427. CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
  428. a2_gid_t gid1, gid2;
  429. CPPUNIT_ASSERT_EQUAL(
  430. 0, GroupId::toNumericId(
  431. gid1, downcast<String>(resParams->get(0))->s().c_str()));
  432. CPPUNIT_ASSERT_EQUAL(
  433. 0, GroupId::toNumericId(
  434. gid2, downcast<String>(resParams->get(1))->s().c_str()));
  435. CPPUNIT_ASSERT(
  436. !File(e_->getOption()->get(PREF_DIR) +
  437. "/c908634fbc257fd56f0114912c2772aeeb4064f4.meta4").exists());
  438. }
  439. e_->getOption()->put(PREF_RPC_SAVE_UPLOAD_METADATA, A2_V_TRUE);
  440. {
  441. auto res = m.execute(createAddMetalinkReq(), e_.get());
  442. CPPUNIT_ASSERT_EQUAL(0, res.code);
  443. const List* resParams = downcast<List>(res.param);
  444. CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
  445. a2_gid_t gid3, gid4;
  446. CPPUNIT_ASSERT_EQUAL(
  447. 0, GroupId::toNumericId(
  448. gid3, downcast<String>(resParams->get(0))->s().c_str()));
  449. CPPUNIT_ASSERT_EQUAL(
  450. 0, GroupId::toNumericId(
  451. gid4, downcast<String>(resParams->get(1))->s().c_str()));
  452. CPPUNIT_ASSERT(
  453. File(e_->getOption()->get(PREF_DIR) +
  454. "/c908634fbc257fd56f0114912c2772aeeb4064f4.meta4").exists());
  455. auto tar = findReservedGroup(e_->getRequestGroupMan().get(), gid3);
  456. CPPUNIT_ASSERT(tar);
  457. CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR) +
  458. "/aria2-5.0.0.tar.bz2",
  459. tar->getFirstFilePath());
  460. auto deb = findReservedGroup(e_->getRequestGroupMan().get(), gid4);
  461. CPPUNIT_ASSERT(deb);
  462. CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR) + "/aria2-5.0.0.deb",
  463. deb->getFirstFilePath());
  464. }
  465. {
  466. auto req = createAddMetalinkReq();
  467. // with options
  468. std::string dir = A2_TEST_OUT_DIR "/aria2_RpcMethodTest_testAddMetalink";
  469. File(dir).mkdirs();
  470. auto opt = Dict::g();
  471. opt->put(PREF_DIR->k, dir);
  472. File(dir + "/c908634fbc257fd56f0114912c2772aeeb4064f4.meta4").remove();
  473. req.params->append(std::move(opt));
  474. auto res = m.execute(std::move(req), e_.get());
  475. CPPUNIT_ASSERT_EQUAL(0, res.code);
  476. const List* resParams = downcast<List>(res.param);
  477. CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
  478. a2_gid_t gid5;
  479. CPPUNIT_ASSERT_EQUAL(
  480. 0, GroupId::toNumericId(
  481. gid5, downcast<String>(resParams->get(0))->s().c_str()));
  482. CPPUNIT_ASSERT_EQUAL(dir + "/aria2-5.0.0.tar.bz2",
  483. findReservedGroup(e_->getRequestGroupMan().get(), gid5)
  484. ->getFirstFilePath());
  485. CPPUNIT_ASSERT(
  486. File(dir + "/c908634fbc257fd56f0114912c2772aeeb4064f4.meta4").exists());
  487. }
  488. }
  489. void RpcMethodTest::testAddMetalink_withoutMetalink()
  490. {
  491. AddMetalinkRpcMethod m;
  492. auto res =
  493. m.execute(createReq(AddMetalinkRpcMethod::getMethodName()), e_.get());
  494. CPPUNIT_ASSERT_EQUAL(1, res.code);
  495. }
  496. void RpcMethodTest::testAddMetalink_notBase64Metalink()
  497. {
  498. AddMetalinkRpcMethod m;
  499. auto req = createReq(AddMetalinkRpcMethod::getMethodName());
  500. req.params->append("not metalink");
  501. auto res = m.execute(std::move(req), e_.get());
  502. CPPUNIT_ASSERT_EQUAL(1, res.code);
  503. }
  504. void RpcMethodTest::testAddMetalink_withPosition()
  505. {
  506. AddUriRpcMethod m1;
  507. auto req1 = createReq(AddUriRpcMethod::getMethodName());
  508. auto urisParam1 = List::g();
  509. urisParam1->append("http://uri");
  510. req1.params->append(std::move(urisParam1));
  511. auto res1 = m1.execute(std::move(req1), e_.get());
  512. CPPUNIT_ASSERT_EQUAL(0, res1.code);
  513. AddMetalinkRpcMethod m2;
  514. auto req2 = createReq(AddMetalinkRpcMethod::getMethodName());
  515. req2.params->append(readFile(A2_TEST_DIR "/2files.metalink"));
  516. req2.params->append(Dict::g());
  517. req2.params->append(Integer::g(0));
  518. auto res2 = m2.execute(std::move(req2), e_.get());
  519. CPPUNIT_ASSERT_EQUAL(0, res2.code);
  520. CPPUNIT_ASSERT_EQUAL(
  521. e_->getOption()->get(PREF_DIR) + "/aria2-5.0.0.tar.bz2",
  522. getReservedGroup(e_->getRequestGroupMan().get(), 0)->getFirstFilePath());
  523. }
  524. #endif // ENABLE_METALINK
  525. void RpcMethodTest::testGetOption()
  526. {
  527. auto group = std::make_shared<RequestGroup>(GroupId::create(), option_);
  528. group->getOption()->put(PREF_DIR, "alpha");
  529. e_->getRequestGroupMan()->addReservedGroup(group);
  530. auto dr = createDownloadResult(error_code::FINISHED, "http://host/fin");
  531. dr->option->put(PREF_DIR, "bravo");
  532. e_->getRequestGroupMan()->addDownloadResult(dr);
  533. GetOptionRpcMethod m;
  534. auto req = createReq(GetOptionRpcMethod::getMethodName());
  535. req.params->append(GroupId::toHex(group->getGID()));
  536. auto res = m.execute(std::move(req), e_.get());
  537. CPPUNIT_ASSERT_EQUAL(0, res.code);
  538. const Dict* resopt = downcast<Dict>(res.param);
  539. CPPUNIT_ASSERT_EQUAL(std::string("alpha"),
  540. downcast<String>(resopt->get(PREF_DIR->k))->s());
  541. req = createReq(GetOptionRpcMethod::getMethodName());
  542. req.params->append(dr->gid->toHex());
  543. res = m.execute(std::move(req), e_.get());
  544. CPPUNIT_ASSERT_EQUAL(0, res.code);
  545. resopt = downcast<Dict>(res.param);
  546. CPPUNIT_ASSERT_EQUAL(std::string("bravo"),
  547. downcast<String>(resopt->get(PREF_DIR->k))->s());
  548. // Invalid GID
  549. req = createReq(GetOptionRpcMethod::getMethodName());
  550. req.params->append(GroupId::create()->toHex());
  551. res = m.execute(std::move(req), e_.get());
  552. CPPUNIT_ASSERT_EQUAL(1, res.code);
  553. }
  554. void RpcMethodTest::testChangeOption()
  555. {
  556. auto group = std::make_shared<RequestGroup>(GroupId::create(), option_);
  557. e_->getRequestGroupMan()->addReservedGroup(group);
  558. ChangeOptionRpcMethod m;
  559. auto req = createReq(ChangeOptionRpcMethod::getMethodName());
  560. req.params->append(GroupId::toHex(group->getGID()));
  561. auto opt = Dict::g();
  562. opt->put(PREF_MAX_DOWNLOAD_LIMIT->k, "100K");
  563. #ifdef ENABLE_BITTORRENT
  564. opt->put(PREF_BT_MAX_PEERS->k, "100");
  565. opt->put(PREF_BT_REQUEST_PEER_SPEED_LIMIT->k, "300K");
  566. opt->put(PREF_MAX_UPLOAD_LIMIT->k, "50K");
  567. {
  568. auto btObject = make_unique<BtObject>();
  569. btObject->btRuntime = std::make_shared<BtRuntime>();
  570. e_->getBtRegistry()->put(group->getGID(), std::move(btObject));
  571. }
  572. #endif // ENABLE_BITTORRENT
  573. req.params->append(std::move(opt));
  574. auto res = m.execute(std::move(req), e_.get());
  575. auto option = group->getOption();
  576. CPPUNIT_ASSERT_EQUAL(0, res.code);
  577. CPPUNIT_ASSERT_EQUAL((int)100_k, group->getMaxDownloadSpeedLimit());
  578. CPPUNIT_ASSERT_EQUAL(std::string("102400"),
  579. option->get(PREF_MAX_DOWNLOAD_LIMIT));
  580. #ifdef ENABLE_BITTORRENT
  581. CPPUNIT_ASSERT_EQUAL(std::string("307200"),
  582. option->get(PREF_BT_REQUEST_PEER_SPEED_LIMIT));
  583. CPPUNIT_ASSERT_EQUAL(std::string("100"), option->get(PREF_BT_MAX_PEERS));
  584. CPPUNIT_ASSERT_EQUAL(
  585. 100, e_->getBtRegistry()->get(group->getGID())->btRuntime->getMaxPeers());
  586. CPPUNIT_ASSERT_EQUAL((int)50_k, group->getMaxUploadSpeedLimit());
  587. CPPUNIT_ASSERT_EQUAL(std::string("51200"),
  588. option->get(PREF_MAX_UPLOAD_LIMIT));
  589. #endif // ENABLE_BITTORRENT
  590. }
  591. void RpcMethodTest::testChangeOption_withBadOption()
  592. {
  593. auto group = std::make_shared<RequestGroup>(GroupId::create(), option_);
  594. e_->getRequestGroupMan()->addReservedGroup(group);
  595. ChangeOptionRpcMethod m;
  596. auto req = createReq(ChangeOptionRpcMethod::getMethodName());
  597. req.params->append(GroupId::toHex(group->getGID()));
  598. auto opt = Dict::g();
  599. opt->put(PREF_MAX_DOWNLOAD_LIMIT->k, "badvalue");
  600. req.params->append(std::move(opt));
  601. auto res = m.execute(std::move(req), e_.get());
  602. CPPUNIT_ASSERT_EQUAL(1, res.code);
  603. }
  604. void RpcMethodTest::testChangeOption_withNotAllowedOption()
  605. {
  606. auto group = std::make_shared<RequestGroup>(GroupId::create(), option_);
  607. e_->getRequestGroupMan()->addReservedGroup(group);
  608. ChangeOptionRpcMethod m;
  609. auto req = createReq(ChangeOptionRpcMethod::getMethodName());
  610. req.params->append(GroupId::toHex(group->getGID()));
  611. auto opt = Dict::g();
  612. opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT->k, "100K");
  613. req.params->append(std::move(opt));
  614. auto res = m.execute(std::move(req), e_.get());
  615. // The unacceptable options are just ignored.
  616. CPPUNIT_ASSERT_EQUAL(0, res.code);
  617. }
  618. void RpcMethodTest::testChangeOption_withoutGid()
  619. {
  620. ChangeOptionRpcMethod m;
  621. auto res =
  622. m.execute(createReq(ChangeOptionRpcMethod::getMethodName()), e_.get());
  623. CPPUNIT_ASSERT_EQUAL(1, res.code);
  624. }
  625. void RpcMethodTest::testChangeGlobalOption()
  626. {
  627. ChangeGlobalOptionRpcMethod m;
  628. auto req = createReq(ChangeGlobalOptionRpcMethod::getMethodName());
  629. auto opt = Dict::g();
  630. opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT->k, "100K");
  631. #ifdef ENABLE_BITTORRENT
  632. opt->put(PREF_MAX_OVERALL_UPLOAD_LIMIT->k, "50K");
  633. #endif // ENABLE_BITTORRENT
  634. req.params->append(std::move(opt));
  635. auto res = m.execute(std::move(req), e_.get());
  636. CPPUNIT_ASSERT_EQUAL(0, res.code);
  637. CPPUNIT_ASSERT_EQUAL(
  638. (int)100_k, e_->getRequestGroupMan()->getMaxOverallDownloadSpeedLimit());
  639. CPPUNIT_ASSERT_EQUAL(std::string("102400"),
  640. e_->getOption()->get(PREF_MAX_OVERALL_DOWNLOAD_LIMIT));
  641. #ifdef ENABLE_BITTORRENT
  642. CPPUNIT_ASSERT_EQUAL(
  643. (int)50_k, e_->getRequestGroupMan()->getMaxOverallUploadSpeedLimit());
  644. CPPUNIT_ASSERT_EQUAL(std::string("51200"),
  645. e_->getOption()->get(PREF_MAX_OVERALL_UPLOAD_LIMIT));
  646. #endif // ENABLE_BITTORRENT
  647. }
  648. void RpcMethodTest::testChangeGlobalOption_withBadOption()
  649. {
  650. ChangeGlobalOptionRpcMethod m;
  651. auto req = createReq(ChangeGlobalOptionRpcMethod::getMethodName());
  652. auto opt = Dict::g();
  653. opt->put(PREF_MAX_OVERALL_DOWNLOAD_LIMIT->k, "badvalue");
  654. req.params->append(std::move(opt));
  655. auto res = m.execute(std::move(req), e_.get());
  656. CPPUNIT_ASSERT_EQUAL(1, res.code);
  657. }
  658. void RpcMethodTest::testChangeGlobalOption_withNotAllowedOption()
  659. {
  660. ChangeGlobalOptionRpcMethod m;
  661. auto req = createReq(ChangeGlobalOptionRpcMethod::getMethodName());
  662. auto opt = Dict::g();
  663. opt->put(PREF_ENABLE_RPC->k, "100K");
  664. req.params->append(std::move(opt));
  665. auto res = m.execute(std::move(req), e_.get());
  666. // The unacceptable options are just ignored.
  667. CPPUNIT_ASSERT_EQUAL(0, res.code);
  668. }
  669. void RpcMethodTest::testNoSuchMethod()
  670. {
  671. NoSuchMethodRpcMethod m;
  672. auto res = m.execute(createReq("make.hamburger"), e_.get());
  673. CPPUNIT_ASSERT_EQUAL(1, res.code);
  674. CPPUNIT_ASSERT_EQUAL(std::string("No such method: make.hamburger"),
  675. getString(downcast<Dict>(res.param), "faultString"));
  676. }
  677. void RpcMethodTest::testTellStatus_withoutGid()
  678. {
  679. TellStatusRpcMethod m;
  680. auto res =
  681. m.execute(createReq(TellStatusRpcMethod::getMethodName()), e_.get());
  682. CPPUNIT_ASSERT_EQUAL(1, res.code);
  683. }
  684. namespace {
  685. void addUri(const std::string& uri, const std::shared_ptr<DownloadEngine>& e)
  686. {
  687. AddUriRpcMethod m;
  688. auto req = createReq(AddUriRpcMethod::getMethodName());
  689. auto urisParam = List::g();
  690. urisParam->append(uri);
  691. req.params->append(std::move(urisParam));
  692. CPPUNIT_ASSERT_EQUAL(0, m.execute(std::move(req), e.get()).code);
  693. }
  694. } // namespace
  695. #ifdef ENABLE_BITTORRENT
  696. namespace {
  697. void addTorrent(const std::string& torrentFile,
  698. const std::shared_ptr<DownloadEngine>& e)
  699. {
  700. AddTorrentRpcMethod m;
  701. auto req = createReq(AddTorrentRpcMethod::getMethodName());
  702. req.params->append(readFile(torrentFile));
  703. auto res = m.execute(std::move(req), e.get());
  704. }
  705. } // namespace
  706. #endif // ENABLE_BITTORRENT
  707. void RpcMethodTest::testTellWaiting()
  708. {
  709. addUri("http://1/", e_);
  710. addUri("http://2/", e_);
  711. addUri("http://3/", e_);
  712. #ifdef ENABLE_BITTORRENT
  713. addTorrent(A2_TEST_DIR "/single.torrent", e_);
  714. #else // !ENABLE_BITTORRENT
  715. addUri("http://4/", e_);
  716. #endif // !ENABLE_BITTORRENT
  717. auto& rgman = e_->getRequestGroupMan();
  718. TellWaitingRpcMethod m;
  719. auto req = createReq(TellWaitingRpcMethod::getMethodName());
  720. req.params->append(Integer::g(1));
  721. req.params->append(Integer::g(2));
  722. auto res = m.execute(std::move(req), e_.get());
  723. CPPUNIT_ASSERT_EQUAL(0, res.code);
  724. const List* resParams = downcast<List>(res.param);
  725. CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
  726. CPPUNIT_ASSERT_EQUAL(
  727. GroupId::toHex(getReservedGroup(rgman.get(), 1)->getGID()),
  728. getString(downcast<Dict>(resParams->get(0)), "gid"));
  729. CPPUNIT_ASSERT_EQUAL(
  730. GroupId::toHex(getReservedGroup(rgman.get(), 2)->getGID()),
  731. getString(downcast<Dict>(resParams->get(1)), "gid"));
  732. // waiting.size() == offset+num
  733. req = createReq(TellWaitingRpcMethod::getMethodName());
  734. req.params->append(Integer::g(1));
  735. req.params->append(Integer::g(3));
  736. res = m.execute(std::move(req), e_.get());
  737. CPPUNIT_ASSERT_EQUAL(0, res.code);
  738. resParams = downcast<List>(res.param);
  739. CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
  740. // waiting.size() < offset+num
  741. req = createReq(TellWaitingRpcMethod::getMethodName());
  742. req.params->append(Integer::g(1));
  743. req.params->append(Integer::g(4));
  744. res = m.execute(std::move(req), e_.get());
  745. CPPUNIT_ASSERT_EQUAL(0, res.code);
  746. resParams = downcast<List>(res.param);
  747. CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
  748. // offset = INT32_MAX
  749. req = createReq(TellWaitingRpcMethod::getMethodName());
  750. req.params->append(Integer::g(INT32_MAX));
  751. req.params->append(Integer::g(1));
  752. res = m.execute(std::move(req), e_.get());
  753. CPPUNIT_ASSERT_EQUAL(0, res.code);
  754. resParams = downcast<List>(res.param);
  755. CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
  756. // num = INT32_MAX
  757. req = createReq(TellWaitingRpcMethod::getMethodName());
  758. req.params->append(Integer::g(1));
  759. req.params->append(Integer::g(INT32_MAX));
  760. res = m.execute(std::move(req), e_.get());
  761. CPPUNIT_ASSERT_EQUAL(0, res.code);
  762. resParams = downcast<List>(res.param);
  763. CPPUNIT_ASSERT_EQUAL((size_t)3, resParams->size());
  764. // offset=INT32_MAX and num = INT32_MAX
  765. req = createReq(TellWaitingRpcMethod::getMethodName());
  766. req.params->append(Integer::g(INT32_MAX));
  767. req.params->append(Integer::g(INT32_MAX));
  768. res = m.execute(std::move(req), e_.get());
  769. CPPUNIT_ASSERT_EQUAL(0, res.code);
  770. resParams = downcast<List>(res.param);
  771. CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
  772. // offset=INT32_MIN and num = INT32_MAX
  773. req = createReq(TellWaitingRpcMethod::getMethodName());
  774. req.params->append(Integer::g(INT32_MIN));
  775. req.params->append(Integer::g(INT32_MAX));
  776. res = m.execute(std::move(req), e_.get());
  777. CPPUNIT_ASSERT_EQUAL(0, res.code);
  778. resParams = downcast<List>(res.param);
  779. CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
  780. // negative offset
  781. req = createReq(TellWaitingRpcMethod::getMethodName());
  782. req.params->append(Integer::g(-1));
  783. req.params->append(Integer::g(2));
  784. res = m.execute(std::move(req), e_.get());
  785. CPPUNIT_ASSERT_EQUAL(0, res.code);
  786. resParams = downcast<List>(res.param);
  787. CPPUNIT_ASSERT_EQUAL((size_t)2, resParams->size());
  788. CPPUNIT_ASSERT_EQUAL(
  789. GroupId::toHex(getReservedGroup(rgman.get(), 3)->getGID()),
  790. getString(downcast<Dict>(resParams->get(0)), "gid"));
  791. CPPUNIT_ASSERT_EQUAL(
  792. GroupId::toHex(getReservedGroup(rgman.get(), 2)->getGID()),
  793. getString(downcast<Dict>(resParams->get(1)), "gid"));
  794. // negative offset and size < num
  795. req = RpcRequest(TellWaitingRpcMethod::getMethodName(), List::g());
  796. req.params->append(Integer::g(-1));
  797. req.params->append(Integer::g(100));
  798. res = m.execute(std::move(req), e_.get());
  799. CPPUNIT_ASSERT_EQUAL(0, res.code);
  800. resParams = downcast<List>(res.param);
  801. CPPUNIT_ASSERT_EQUAL((size_t)4, resParams->size());
  802. // nagative offset and normalized offset < 0
  803. req = RpcRequest(TellWaitingRpcMethod::getMethodName(), List::g());
  804. req.params->append(Integer::g(-5));
  805. req.params->append(Integer::g(100));
  806. res = m.execute(std::move(req), e_.get());
  807. CPPUNIT_ASSERT_EQUAL(0, res.code);
  808. resParams = downcast<List>(res.param);
  809. CPPUNIT_ASSERT_EQUAL((size_t)0, resParams->size());
  810. // nagative offset and normalized offset == 0
  811. req = RpcRequest(TellWaitingRpcMethod::getMethodName(), List::g());
  812. req.params->append(Integer::g(-4));
  813. req.params->append(Integer::g(100));
  814. res = m.execute(std::move(req), e_.get());
  815. CPPUNIT_ASSERT_EQUAL(0, res.code);
  816. resParams = downcast<List>(res.param);
  817. CPPUNIT_ASSERT_EQUAL((size_t)1, resParams->size());
  818. }
  819. void RpcMethodTest::testTellWaiting_fail()
  820. {
  821. TellWaitingRpcMethod m;
  822. auto res =
  823. m.execute(createReq(TellWaitingRpcMethod::getMethodName()), e_.get());
  824. CPPUNIT_ASSERT_EQUAL(1, res.code);
  825. }
  826. void RpcMethodTest::testGetVersion()
  827. {
  828. GetVersionRpcMethod m;
  829. auto res =
  830. m.execute(createReq(GetVersionRpcMethod::getMethodName()), e_.get());
  831. CPPUNIT_ASSERT_EQUAL(0, res.code);
  832. const Dict* resParams = downcast<Dict>(res.param);
  833. CPPUNIT_ASSERT_EQUAL(std::string(PACKAGE_VERSION),
  834. getString(resParams, "version"));
  835. const List* featureList = downcast<List>(resParams->get("enabledFeatures"));
  836. std::string features;
  837. for (auto i = featureList->begin(); i != featureList->end(); ++i) {
  838. const String* s = downcast<String>(*i);
  839. features += s->s();
  840. features += ", ";
  841. }
  842. CPPUNIT_ASSERT_EQUAL(featureSummary() + ", ", features);
  843. }
  844. void RpcMethodTest::testGatherStoppedDownload()
  845. {
  846. std::vector<std::shared_ptr<FileEntry>> fileEntries;
  847. std::vector<a2_gid_t> followedBy;
  848. followedBy.push_back(3);
  849. followedBy.push_back(4);
  850. auto d = std::make_shared<DownloadResult>();
  851. d->gid = GroupId::create();
  852. d->fileEntries = fileEntries;
  853. d->inMemoryDownload = false;
  854. d->sessionDownloadLength = UINT64_MAX;
  855. d->sessionTime = 1_s;
  856. d->result = error_code::FINISHED;
  857. d->followedBy = followedBy;
  858. d->following = 1;
  859. d->belongsTo = 2;
  860. auto entry = Dict::g();
  861. std::vector<std::string> keys;
  862. gatherStoppedDownload(entry.get(), d, keys);
  863. const List* followedByRes = downcast<List>(entry->get("followedBy"));
  864. CPPUNIT_ASSERT_EQUAL(GroupId::toHex(3),
  865. downcast<String>(followedByRes->get(0))->s());
  866. CPPUNIT_ASSERT_EQUAL(GroupId::toHex(4),
  867. downcast<String>(followedByRes->get(1))->s());
  868. CPPUNIT_ASSERT_EQUAL(GroupId::toHex(1),
  869. downcast<String>(entry->get("following"))->s());
  870. CPPUNIT_ASSERT_EQUAL(GroupId::toHex(2),
  871. downcast<String>(entry->get("belongsTo"))->s());
  872. keys.push_back("gid");
  873. entry = Dict::g();
  874. gatherStoppedDownload(entry.get(), d, keys);
  875. CPPUNIT_ASSERT_EQUAL((size_t)1, entry->size());
  876. CPPUNIT_ASSERT(entry->containsKey("gid"));
  877. }
  878. void RpcMethodTest::testGatherProgressCommon()
  879. {
  880. auto dctx = std::make_shared<DownloadContext>(0, 0, "aria2.tar.bz2");
  881. std::string uris[] = {"http://localhost/aria2.tar.bz2"};
  882. dctx->getFirstFileEntry()->addUris(std::begin(uris), std::end(uris));
  883. auto group =
  884. std::make_shared<RequestGroup>(GroupId::create(), util::copy(option_));
  885. group->setDownloadContext(dctx);
  886. std::vector<std::shared_ptr<RequestGroup>> followedBy;
  887. for (int i = 0; i < 2; ++i) {
  888. followedBy.push_back(
  889. std::make_shared<RequestGroup>(GroupId::create(), util::copy(option_)));
  890. }
  891. group->followedBy(followedBy.begin(), followedBy.end());
  892. auto leader = GroupId::create();
  893. group->following(leader->getNumericId());
  894. auto parent = GroupId::create();
  895. group->belongsTo(parent->getNumericId());
  896. auto entry = Dict::g();
  897. std::vector<std::string> keys;
  898. gatherProgressCommon(entry.get(), group, keys);
  899. const List* followedByRes = downcast<List>(entry->get("followedBy"));
  900. CPPUNIT_ASSERT_EQUAL(GroupId::toHex(followedBy[0]->getGID()),
  901. downcast<String>(followedByRes->get(0))->s());
  902. CPPUNIT_ASSERT_EQUAL(GroupId::toHex(followedBy[1]->getGID()),
  903. downcast<String>(followedByRes->get(1))->s());
  904. CPPUNIT_ASSERT_EQUAL(leader->toHex(),
  905. downcast<String>(entry->get("following"))->s());
  906. CPPUNIT_ASSERT_EQUAL(parent->toHex(),
  907. downcast<String>(entry->get("belongsTo"))->s());
  908. const List* files = downcast<List>(entry->get("files"));
  909. CPPUNIT_ASSERT_EQUAL((size_t)1, files->size());
  910. const Dict* file = downcast<Dict>(files->get(0));
  911. CPPUNIT_ASSERT_EQUAL(std::string("aria2.tar.bz2"),
  912. downcast<String>(file->get("path"))->s());
  913. CPPUNIT_ASSERT_EQUAL(
  914. uris[0], downcast<String>(downcast<Dict>(downcast<List>(file->get("uris"))
  915. ->get(0))->get("uri"))->s());
  916. CPPUNIT_ASSERT_EQUAL(e_->getOption()->get(PREF_DIR),
  917. downcast<String>(entry->get("dir"))->s());
  918. keys.push_back("gid");
  919. entry = Dict::g();
  920. gatherProgressCommon(entry.get(), group, keys);
  921. CPPUNIT_ASSERT_EQUAL((size_t)1, entry->size());
  922. CPPUNIT_ASSERT(entry->containsKey("gid"));
  923. }
  924. #ifdef ENABLE_BITTORRENT
  925. void RpcMethodTest::testGatherBitTorrentMetadata()
  926. {
  927. auto option = std::make_shared<Option>();
  928. option->put(PREF_DIR, ".");
  929. auto dctx = std::make_shared<DownloadContext>();
  930. bittorrent::load(A2_TEST_DIR "/test.torrent", dctx, option);
  931. auto btDict = Dict::g();
  932. gatherBitTorrentMetadata(btDict.get(), bittorrent::getTorrentAttrs(dctx));
  933. CPPUNIT_ASSERT_EQUAL(std::string("REDNOAH.COM RULES"),
  934. downcast<String>(btDict->get("comment"))->s());
  935. CPPUNIT_ASSERT_EQUAL((int64_t)1123456789,
  936. downcast<Integer>(btDict->get("creationDate"))->i());
  937. CPPUNIT_ASSERT_EQUAL(std::string("multi"),
  938. downcast<String>(btDict->get("mode"))->s());
  939. CPPUNIT_ASSERT_EQUAL(
  940. std::string("aria2-test"),
  941. downcast<String>(downcast<Dict>(btDict->get("info"))->get("name"))->s());
  942. const List* announceList = downcast<List>(btDict->get("announceList"));
  943. CPPUNIT_ASSERT_EQUAL((size_t)3, announceList->size());
  944. CPPUNIT_ASSERT_EQUAL(
  945. std::string("http://tracker1"),
  946. downcast<String>(downcast<List>(announceList->get(0))->get(0))->s());
  947. CPPUNIT_ASSERT_EQUAL(
  948. std::string("http://tracker2"),
  949. downcast<String>(downcast<List>(announceList->get(1))->get(0))->s());
  950. CPPUNIT_ASSERT_EQUAL(
  951. std::string("http://tracker3"),
  952. downcast<String>(downcast<List>(announceList->get(2))->get(0))->s());
  953. // Remove some keys
  954. auto modBtAttrs = bittorrent::getTorrentAttrs(dctx);
  955. modBtAttrs->comment.clear();
  956. modBtAttrs->creationDate = 0;
  957. modBtAttrs->mode = BT_FILE_MODE_NONE;
  958. modBtAttrs->metadata.clear();
  959. btDict = Dict::g();
  960. gatherBitTorrentMetadata(btDict.get(), modBtAttrs);
  961. CPPUNIT_ASSERT(!btDict->containsKey("comment"));
  962. CPPUNIT_ASSERT(!btDict->containsKey("creationDate"));
  963. CPPUNIT_ASSERT(!btDict->containsKey("mode"));
  964. CPPUNIT_ASSERT(!btDict->containsKey("info"));
  965. CPPUNIT_ASSERT(btDict->containsKey("announceList"));
  966. }
  967. #endif // ENABLE_BITTORRENT
  968. void RpcMethodTest::testChangePosition()
  969. {
  970. e_->getRequestGroupMan()->addReservedGroup(
  971. std::make_shared<RequestGroup>(GroupId::create(), util::copy(option_)));
  972. e_->getRequestGroupMan()->addReservedGroup(
  973. std::make_shared<RequestGroup>(GroupId::create(), util::copy(option_)));
  974. a2_gid_t gid = getReservedGroup(e_->getRequestGroupMan().get(), 0)->getGID();
  975. ChangePositionRpcMethod m;
  976. auto req = createReq(ChangePositionRpcMethod::getMethodName());
  977. req.params->append(GroupId::toHex(gid));
  978. req.params->append(Integer::g(1));
  979. req.params->append("POS_SET");
  980. auto res = m.execute(std::move(req), e_.get());
  981. CPPUNIT_ASSERT_EQUAL(0, res.code);
  982. CPPUNIT_ASSERT_EQUAL((int64_t)1, downcast<Integer>(res.param)->i());
  983. CPPUNIT_ASSERT_EQUAL(
  984. gid, getReservedGroup(e_->getRequestGroupMan().get(), 1)->getGID());
  985. }
  986. void RpcMethodTest::testChangePosition_fail()
  987. {
  988. ChangePositionRpcMethod m;
  989. auto res =
  990. m.execute(createReq(ChangePositionRpcMethod::getMethodName()), e_.get());
  991. CPPUNIT_ASSERT_EQUAL(1, res.code);
  992. auto req = createReq(ChangePositionRpcMethod::getMethodName());
  993. req.params->append("1");
  994. req.params->append(Integer::g(2));
  995. req.params->append("bad keyword");
  996. res = m.execute(std::move(req), e_.get());
  997. CPPUNIT_ASSERT_EQUAL(1, res.code);
  998. }
  999. namespace {
  1000. RpcRequest createChangeUriReq(a2_gid_t gid, size_t fileIndex)
  1001. {
  1002. auto req = createReq(ChangeUriRpcMethod::getMethodName());
  1003. req.params->append(GroupId::toHex(gid)); // GID
  1004. req.params->append(Integer::g(fileIndex)); // index of FileEntry
  1005. auto removeuris = List::g();
  1006. removeuris->append("http://example.org/mustremove1");
  1007. removeuris->append("http://example.org/mustremove2");
  1008. removeuris->append("http://example.org/notexist");
  1009. req.params->append(std::move(removeuris));
  1010. return req;
  1011. }
  1012. } // namespace
  1013. void RpcMethodTest::testChangeUri()
  1014. {
  1015. std::shared_ptr<FileEntry> files[3];
  1016. for (int i = 0; i < 3; ++i) {
  1017. files[i].reset(new FileEntry());
  1018. }
  1019. files[1]->addUri("http://example.org/aria2.tar.bz2");
  1020. files[1]->addUri("http://example.org/mustremove1");
  1021. files[1]->addUri("http://example.org/mustremove2");
  1022. auto dctx = std::make_shared<DownloadContext>();
  1023. dctx->setFileEntries(&files[0], &files[3]);
  1024. auto group = std::make_shared<RequestGroup>(GroupId::create(), option_);
  1025. group->setDownloadContext(dctx);
  1026. e_->getRequestGroupMan()->addReservedGroup(group);
  1027. ChangeUriRpcMethod m;
  1028. auto req = createChangeUriReq(group->getGID(), 2);
  1029. auto adduris = List::g();
  1030. adduris->append("http://example.org/added1");
  1031. adduris->append("http://example.org/added2");
  1032. adduris->append("baduri");
  1033. adduris->append("http://example.org/added3");
  1034. req.params->append(std::move(adduris));
  1035. auto res = m.execute(std::move(req), e_.get());
  1036. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1037. CPPUNIT_ASSERT_EQUAL(
  1038. (int64_t)2, downcast<Integer>(downcast<List>(res.param)->get(0))->i());
  1039. CPPUNIT_ASSERT_EQUAL(
  1040. (int64_t)3, downcast<Integer>(downcast<List>(res.param)->get(1))->i());
  1041. CPPUNIT_ASSERT_EQUAL((size_t)0, files[0]->getRemainingUris().size());
  1042. CPPUNIT_ASSERT_EQUAL((size_t)0, files[2]->getRemainingUris().size());
  1043. std::deque<std::string> uris = files[1]->getRemainingUris();
  1044. CPPUNIT_ASSERT_EQUAL((size_t)4, uris.size());
  1045. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/aria2.tar.bz2"),
  1046. uris[0]);
  1047. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1"), uris[1]);
  1048. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added2"), uris[2]);
  1049. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added3"), uris[3]);
  1050. req = createChangeUriReq(group->getGID(), 2);
  1051. // Change adduris
  1052. adduris = List::g();
  1053. adduris->append("http://example.org/added1-1");
  1054. adduris->append("http://example.org/added1-2");
  1055. req.params->append(std::move(adduris));
  1056. // Set position parameter
  1057. req.params->append(Integer::g(2));
  1058. res = m.execute(std::move(req), e_.get());
  1059. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1060. CPPUNIT_ASSERT_EQUAL(
  1061. (int64_t)0, downcast<Integer>(downcast<List>(res.param)->get(0))->i());
  1062. CPPUNIT_ASSERT_EQUAL(
  1063. (int64_t)2, downcast<Integer>(downcast<List>(res.param)->get(1))->i());
  1064. uris = files[1]->getRemainingUris();
  1065. CPPUNIT_ASSERT_EQUAL((size_t)6, uris.size());
  1066. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-1"), uris[2]);
  1067. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-2"), uris[3]);
  1068. // Change index of FileEntry
  1069. req = createChangeUriReq(group->getGID(), 1);
  1070. adduris = List::g();
  1071. adduris->append("http://example.org/added1-1");
  1072. adduris->append("http://example.org/added1-2");
  1073. req.params->append(std::move(adduris));
  1074. // Set position far beyond the size of uris in FileEntry.
  1075. req.params->append(Integer::g(1000));
  1076. res = m.execute(std::move(req), e_.get());
  1077. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1078. CPPUNIT_ASSERT_EQUAL(
  1079. (int64_t)0, downcast<Integer>(downcast<List>(res.param)->get(0))->i());
  1080. CPPUNIT_ASSERT_EQUAL(
  1081. (int64_t)2, downcast<Integer>(downcast<List>(res.param)->get(1))->i());
  1082. uris = files[0]->getRemainingUris();
  1083. CPPUNIT_ASSERT_EQUAL((size_t)2, uris.size());
  1084. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-1"), uris[0]);
  1085. CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/added1-2"), uris[1]);
  1086. }
  1087. namespace {
  1088. RpcRequest createChangeUriEmptyReq(a2_gid_t gid, size_t fileIndex)
  1089. {
  1090. auto req = createReq(ChangeUriRpcMethod::getMethodName());
  1091. req.params->append(GroupId::toHex(gid)); // GID
  1092. req.params->append(Integer::g(fileIndex)); // index of FileEntry
  1093. req.params->append(List::g()); // remove uris
  1094. req.params->append(List::g()); // append uris
  1095. return req;
  1096. }
  1097. } // namespace
  1098. void RpcMethodTest::testChangeUri_fail()
  1099. {
  1100. std::shared_ptr<FileEntry> files[3];
  1101. for (int i = 0; i < 3; ++i) {
  1102. files[i] = std::make_shared<FileEntry>();
  1103. }
  1104. auto dctx = std::make_shared<DownloadContext>();
  1105. dctx->setFileEntries(&files[0], &files[3]);
  1106. auto group = std::make_shared<RequestGroup>(GroupId::create(), option_);
  1107. group->setDownloadContext(dctx);
  1108. e_->getRequestGroupMan()->addReservedGroup(group);
  1109. ChangeUriRpcMethod m;
  1110. auto req = createChangeUriEmptyReq(group->getGID(), 1);
  1111. auto res = m.execute(std::move(req), e_.get());
  1112. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1113. req = createChangeUriEmptyReq(group->getGID(), 0);
  1114. res = m.execute(std::move(req), e_.get());
  1115. // RPC request fails because 2nd argument is less than 1.
  1116. CPPUNIT_ASSERT_EQUAL(1, res.code);
  1117. req = createChangeUriEmptyReq(GroupId::create()->getNumericId(), 1);
  1118. res = m.execute(std::move(req), e_.get());
  1119. // RPC request fails because the given GID does not exist.
  1120. CPPUNIT_ASSERT_EQUAL(1, res.code);
  1121. req = createChangeUriEmptyReq(group->getGID(), 4);
  1122. res = m.execute(std::move(req), e_.get());
  1123. // RPC request fails because FileEntry#3 does not exist.
  1124. CPPUNIT_ASSERT_EQUAL(1, res.code);
  1125. req = createChangeUriEmptyReq(group->getGID(), 1);
  1126. req.params->set(1, String::g("0"));
  1127. res = m.execute(std::move(req), e_.get());
  1128. // RPC request fails because index of FileEntry is string.
  1129. CPPUNIT_ASSERT_EQUAL(1, res.code);
  1130. req = createChangeUriEmptyReq(group->getGID(), 1);
  1131. req.params->set(2, String::g("http://url"));
  1132. res = m.execute(std::move(req), e_.get());
  1133. // RPC request fails because 3rd param is not list.
  1134. CPPUNIT_ASSERT_EQUAL(1, res.code);
  1135. req = createChangeUriEmptyReq(group->getGID(), 1);
  1136. req.params->set(2, List::g());
  1137. req.params->set(3, String::g("http://url"));
  1138. res = m.execute(std::move(req), e_.get());
  1139. // RPC request fails because 4th param is not list.
  1140. CPPUNIT_ASSERT_EQUAL(1, res.code);
  1141. }
  1142. void RpcMethodTest::testGetSessionInfo()
  1143. {
  1144. GetSessionInfoRpcMethod m;
  1145. auto res =
  1146. m.execute(createReq(GetSessionInfoRpcMethod::getMethodName()), e_.get());
  1147. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1148. CPPUNIT_ASSERT_EQUAL(util::toHex(e_->getSessionId()),
  1149. getString(downcast<Dict>(res.param), "sessionId"));
  1150. }
  1151. void RpcMethodTest::testPause()
  1152. {
  1153. std::vector<std::string> uris{
  1154. "http://url1", "http://url2", "http://url3",
  1155. };
  1156. option_->put(PREF_FORCE_SEQUENTIAL, A2_V_TRUE);
  1157. std::vector<std::shared_ptr<RequestGroup>> groups;
  1158. createRequestGroupForUri(groups, option_, uris);
  1159. CPPUNIT_ASSERT_EQUAL((size_t)3, groups.size());
  1160. e_->getRequestGroupMan()->addReservedGroup(groups);
  1161. {
  1162. PauseRpcMethod m;
  1163. auto req = createReq(PauseRpcMethod::getMethodName());
  1164. req.params->append(GroupId::toHex(groups[0]->getGID()));
  1165. auto res = m.execute(std::move(req), e_.get());
  1166. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1167. }
  1168. CPPUNIT_ASSERT(groups[0]->isPauseRequested());
  1169. {
  1170. UnpauseRpcMethod m;
  1171. auto req = createReq(UnpauseRpcMethod::getMethodName());
  1172. req.params->append(GroupId::toHex(groups[0]->getGID()));
  1173. auto res = m.execute(std::move(req), e_.get());
  1174. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1175. }
  1176. CPPUNIT_ASSERT(!groups[0]->isPauseRequested());
  1177. {
  1178. PauseAllRpcMethod m;
  1179. auto req = createReq(PauseAllRpcMethod::getMethodName());
  1180. auto res = m.execute(std::move(req), e_.get());
  1181. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1182. }
  1183. for (size_t i = 0; i < groups.size(); ++i) {
  1184. CPPUNIT_ASSERT(groups[i]->isPauseRequested());
  1185. }
  1186. {
  1187. UnpauseAllRpcMethod m;
  1188. auto req = createReq(UnpauseAllRpcMethod::getMethodName());
  1189. auto res = m.execute(std::move(req), e_.get());
  1190. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1191. }
  1192. for (size_t i = 0; i < groups.size(); ++i) {
  1193. CPPUNIT_ASSERT(!groups[i]->isPauseRequested());
  1194. }
  1195. {
  1196. ForcePauseAllRpcMethod m;
  1197. auto req = createReq(ForcePauseAllRpcMethod::getMethodName());
  1198. auto res = m.execute(std::move(req), e_.get());
  1199. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1200. }
  1201. for (size_t i = 0; i < groups.size(); ++i) {
  1202. CPPUNIT_ASSERT(groups[i]->isPauseRequested());
  1203. }
  1204. }
  1205. void RpcMethodTest::testSystemMulticall()
  1206. {
  1207. SystemMulticallRpcMethod m;
  1208. auto req = createReq("system.multicall");
  1209. auto reqparams = List::g();
  1210. for (int i = 0; i < 2; ++i) {
  1211. auto dict = Dict::g();
  1212. dict->put("methodName", AddUriRpcMethod::getMethodName());
  1213. auto params = List::g();
  1214. auto urisParam = List::g();
  1215. urisParam->append("http://localhost/" + util::itos(i));
  1216. params->append(std::move(urisParam));
  1217. dict->put("params", std::move(params));
  1218. reqparams->append(std::move(dict));
  1219. }
  1220. {
  1221. auto dict = Dict::g();
  1222. dict->put("methodName", "not exists");
  1223. dict->put("params", List::g());
  1224. reqparams->append(std::move(dict));
  1225. }
  1226. {
  1227. reqparams->append("not struct");
  1228. }
  1229. {
  1230. auto dict = Dict::g();
  1231. dict->put("methodName", "system.multicall");
  1232. dict->put("params", List::g());
  1233. reqparams->append(std::move(dict));
  1234. }
  1235. {
  1236. // missing params
  1237. auto dict = Dict::g();
  1238. dict->put("methodName", GetVersionRpcMethod::getMethodName());
  1239. reqparams->append(std::move(dict));
  1240. }
  1241. {
  1242. auto dict = Dict::g();
  1243. dict->put("methodName", GetVersionRpcMethod::getMethodName());
  1244. dict->put("params", List::g());
  1245. reqparams->append(std::move(dict));
  1246. }
  1247. req.params->append(std::move(reqparams));
  1248. auto res = m.execute(std::move(req), e_.get());
  1249. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1250. const List* resParams = downcast<List>(res.param);
  1251. CPPUNIT_ASSERT_EQUAL((size_t)7, resParams->size());
  1252. auto& rgman = e_->getRequestGroupMan();
  1253. CPPUNIT_ASSERT_EQUAL(
  1254. GroupId::toHex(getReservedGroup(rgman.get(), 0)->getGID()),
  1255. downcast<String>(downcast<List>(resParams->get(0))->get(0))->s());
  1256. CPPUNIT_ASSERT_EQUAL(
  1257. GroupId::toHex(getReservedGroup(rgman.get(), 1)->getGID()),
  1258. downcast<String>(downcast<List>(resParams->get(1))->get(0))->s());
  1259. CPPUNIT_ASSERT_EQUAL((int64_t)1,
  1260. downcast<Integer>(downcast<Dict>(resParams->get(2))
  1261. ->get("faultCode"))->i());
  1262. CPPUNIT_ASSERT_EQUAL((int64_t)1,
  1263. downcast<Integer>(downcast<Dict>(resParams->get(3))
  1264. ->get("faultCode"))->i());
  1265. CPPUNIT_ASSERT_EQUAL((int64_t)1,
  1266. downcast<Integer>(downcast<Dict>(resParams->get(4))
  1267. ->get("faultCode"))->i());
  1268. CPPUNIT_ASSERT(downcast<List>(resParams->get(5)));
  1269. CPPUNIT_ASSERT(downcast<List>(resParams->get(6)));
  1270. }
  1271. void RpcMethodTest::testSystemMulticall_fail()
  1272. {
  1273. SystemMulticallRpcMethod m;
  1274. auto res = m.execute(createReq("system.multicall"), e_.get());
  1275. CPPUNIT_ASSERT_EQUAL(1, res.code);
  1276. }
  1277. void RpcMethodTest::testSystemListMethods()
  1278. {
  1279. SystemListMethodsRpcMethod m;
  1280. auto res = m.execute(createReq("system.listMethods"), e_.get());
  1281. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1282. const auto resParams = downcast<List>(res.param);
  1283. auto& allNames = allMethodNames();
  1284. CPPUNIT_ASSERT_EQUAL(allNames.size(), resParams->size());
  1285. for (size_t i = 0; i < allNames.size(); ++i) {
  1286. const auto s = downcast<String>(resParams->get(i));
  1287. CPPUNIT_ASSERT(s);
  1288. CPPUNIT_ASSERT_EQUAL(allNames[i], s->s());
  1289. }
  1290. }
  1291. void RpcMethodTest::testSystemListNotifications()
  1292. {
  1293. SystemListNotificationsRpcMethod m;
  1294. auto res = m.execute(createReq("system.listNotifications"), e_.get());
  1295. CPPUNIT_ASSERT_EQUAL(0, res.code);
  1296. const auto resParams = downcast<List>(res.param);
  1297. auto& allNames = allNotificationsNames();
  1298. CPPUNIT_ASSERT_EQUAL(allNames.size(), resParams->size());
  1299. for (size_t i = 0; i < allNames.size(); ++i) {
  1300. const auto s = downcast<String>(resParams->get(i));
  1301. CPPUNIT_ASSERT(s);
  1302. CPPUNIT_ASSERT_EQUAL(allNames[i], s->s());
  1303. }
  1304. }
  1305. } // namespace rpc
  1306. } // namespace aria2