TorrentParserTest.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "../TorrentParser.h"
00025 #include "TorrentLoadFunctions.h"
00026 #include "Imports.cpp"
00027 
00028 namespace Protocols {
00029 namespace BitTorrent {
00030 namespace Torrents {
00031 namespace Testing {
00032 
00034 
00038 class TorrentParserTest : public CppUnit::TestFixture
00039 {
00040     CPPUNIT_TEST_SUITE (TorrentParserTest);
00041     CPPUNIT_TEST (testLoadTorrentDataMissingAnnounce);
00042     CPPUNIT_TEST (testLoadTorrentDataMissingPieceLength);
00043     CPPUNIT_TEST (testLoadTorrentDataMissingPieces);
00044     CPPUNIT_TEST (testLoadTorrentDataMissingInfo);
00045     CPPUNIT_TEST (testLoadTorrentDataInvalidAnnounce);
00046     CPPUNIT_TEST (testLoadTorrentDataNegativeCreationDate);
00047     CPPUNIT_TEST (testLoadTorrentDataZeroCreationDate);
00048     CPPUNIT_TEST (testLoadTorrentDataNegativePieceLength);
00049     CPPUNIT_TEST (testLoadTorrentDataZeroPieceLength);
00050     CPPUNIT_TEST (testLoadTorrentDataInvalidPiecesLength);
00051     CPPUNIT_TEST (testLoadTorrentDataNegativePrivate);
00052     CPPUNIT_TEST (testLoadTorrentDataZeroPrivate);
00053     CPPUNIT_TEST (testLoadTorrentDataOnePrivate);
00054     CPPUNIT_TEST (testLoadTorrentDataTooHighPrivate);
00055     CPPUNIT_TEST (testAnnounceListParsingOneTierOneTracker);
00056     CPPUNIT_TEST (testAnnounceListParsingOneTierManyTrackers);
00057     CPPUNIT_TEST (testAnnounceListParsingManyTiersOneTracker);
00058     CPPUNIT_TEST (testAnnounceListParsingManyTiersManyTrackers);
00059     CPPUNIT_TEST (testAnnounceListParsingOneTierNoTracker);
00060     CPPUNIT_TEST (testAnnounceListParsingNestedTiers);
00061     CPPUNIT_TEST (testLoadTorrentDataFileInfoMissingFileInfo);
00062     CPPUNIT_TEST (testLoadTorrentDataFileInfoMissingFileName);
00063     CPPUNIT_TEST (testLoadTorrentDataFileInfoMissingFileLength);
00064     CPPUNIT_TEST (testLoadTorrentDataFileInfoNegativeFileLength);
00065     CPPUNIT_TEST (testLoadTorrentDataFileInfoZeroFileLength);
00066     CPPUNIT_TEST (testLoadTorrentDataFileInfoValidChecksum);
00067     CPPUNIT_TEST (testLoadTorrentDataFileInfoTooShortChecksum);
00068     CPPUNIT_TEST (testLoadTorrentDataFileInfoTooLongChecksum);
00069     CPPUNIT_TEST (testLoadTorrentDataMultipleFileInfoMissingDirectoryName);
00070     CPPUNIT_TEST (testLoadTorrentDataMultipleFileInfoMissingFiles);
00071     CPPUNIT_TEST (testLoadTorrentDataMultipleFileInfoMissingFileLength);
00072     CPPUNIT_TEST (testLoadTorrentDataMultipleFileInfoMissingFilePath);
00073     CPPUNIT_TEST (testFilePathParsingNoFiles);
00074     CPPUNIT_TEST (testFilePathParsingOnlyFile);
00075     CPPUNIT_TEST (testFilePathParsingOneDirectory);
00076     CPPUNIT_TEST (testFilePathParsingMoreDirectories);
00077     CPPUNIT_TEST (testLoadTorrentDataSimpleTorrent);
00078     CPPUNIT_TEST (testLoadTorrentDataMoreComplexTorrent);
00079     CPPUNIT_TEST (testLoadTorrentDataTorrentWithEverything);
00080     CPPUNIT_TEST (testLoadTorrentDataMinimalTorrent);
00081     CPPUNIT_TEST (testLoadTorrentDataEmptyTorrent);
00082     CPPUNIT_TEST_SUITE_END();
00083 
00085     static int sumOfAllPiecesLength (const Torrent::PieceList &pieceList)
00086     {
00087         return Torrent::Piece::size() * pieceList.size();
00088     }
00089 
00090 public:
00092     void testLoadTorrentDataMissingAnnounce()
00093     {
00094         QByteArray rawTorrentData ("d4:infod6:lengthi6e4:name8:file.txt"
00095             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00096         Torrent torrent;
00097         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00098         CPPUNIT_ASSERT (!loadedOk);
00099     }
00100 
00102     void testLoadTorrentDataMissingPieceLength()
00103     {
00104         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00105             "4:infod6:lengthi6e4:name8:file.txt"
00106             "6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00107         Torrent torrent;
00108         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00109         CPPUNIT_ASSERT (!loadedOk);
00110     }
00111 
00113     void testLoadTorrentDataMissingPieces()
00114     {
00115         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00116             "4:infod6:lengthi6e4:name8:file.txt12:piece lengthi32768eee");
00117         Torrent torrent;
00118         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00119         CPPUNIT_ASSERT (!loadedOk);
00120     }
00121 
00123     void testLoadTorrentDataMissingInfo()
00124     {
00125         QByteArray rawTorrentData ("d8:announce18:http://tracker.come");
00126         Torrent torrent;
00127         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00128         CPPUNIT_ASSERT (!loadedOk);
00129     }
00130 
00132     void testLoadTorrentDataInvalidAnnounce()
00133     {
00134         QByteArray rawTorrentData ("d8:announce1::"
00135             "4:infod6:lengthi6e4:name8:file.txt7:privatei1e"
00136             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00137         Torrent torrent;
00138         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00139         CPPUNIT_ASSERT (!loadedOk);
00140     }
00141 
00143     void testLoadTorrentDataNegativeCreationDate()
00144     {
00145         QByteArray rawTorrentData ("d8:announce18:http://tracker.com13:creation datei-1234511e"
00146             "4:infod6:lengthi6e4:name8:file.txt"
00147             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00148         Torrent torrent;
00149         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00150         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00151         CPPUNIT_ASSERT (torrent.creationDate() == QDateTime());
00152     }
00153 
00155     void testLoadTorrentDataZeroCreationDate()
00156     {
00157         QByteArray rawTorrentData ("d8:announce18:http://tracker.com13:creation datei0e"
00158             "4:infod6:lengthi6e4:name8:file.txt"
00159             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00160         Torrent torrent;
00161         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00162         CPPUNIT_ASSERT (loadedOk);
00163         CPPUNIT_ASSERT (torrent.creationDate().toTime_t() == 0);
00164     }
00165 
00167     void testLoadTorrentDataNegativePieceLength()
00168     {
00169         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00170             "4:infod6:lengthi6e4:name8:file.txt"
00171             "12:piece lengthi-100e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00172         Torrent torrent;
00173         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00174         CPPUNIT_ASSERT (!loadedOk);
00175     }
00176 
00178     void testLoadTorrentDataZeroPieceLength()
00179     {
00180         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00181             "4:infod6:lengthi6e4:name8:file.txt"
00182             "12:piece lengthi0e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00183         Torrent torrent;
00184         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00185         CPPUNIT_ASSERT (!loadedOk);
00186     }
00187 
00189     void testLoadTorrentDataInvalidPiecesLength()
00190     {
00191         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00192             "4:infod6:lengthi6e4:name8:file.txt"
00193             "12:piece lengthi32768e6:pieces5:XXXXXee");
00194         Torrent torrent;
00195         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00196         CPPUNIT_ASSERT (!loadedOk);
00197     }
00198 
00200     void testLoadTorrentDataNegativePrivate()
00201     {
00202         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00203             "4:infod6:lengthi6e4:name8:file.txt7:privatei-10e"
00204             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00205         Torrent torrent;
00206         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00207         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00208         CPPUNIT_ASSERT (!torrent.isPrivate());
00209     }
00210 
00212     void testLoadTorrentDataZeroPrivate()
00213     {
00214         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00215             "4:infod6:lengthi6e4:name8:file.txt7:privatei0e"
00216             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00217         Torrent torrent;
00218         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00219         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00220         CPPUNIT_ASSERT (!torrent.isPrivate());
00221     }
00222 
00224     void testLoadTorrentDataOnePrivate()
00225     {
00226         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00227             "4:infod6:lengthi6e4:name8:file.txt7:privatei1e"
00228             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00229         Torrent torrent;
00230         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00231         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00232         CPPUNIT_ASSERT (torrent.isPrivate());
00233     }
00234 
00236     void testLoadTorrentDataTooHighPrivate()
00237     {
00238         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00239             "4:infod6:lengthi6e4:name8:file.txt7:privatei353e"
00240             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00241         Torrent torrent;
00242         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00243         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00244         CPPUNIT_ASSERT (!torrent.isPrivate());
00245     }
00246 
00248     void testAnnounceListParsingOneTierOneTracker()
00249     {
00250         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00251             "13:announce-listll19:http://tracker1.comee"
00252             "4:infod6:lengthi6e4:name8:file.txt"
00253             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00254         Torrent torrent;
00255         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00256         CPPUNIT_ASSERT (loadedOk);
00257 
00258         Torrent::AnnounceList referenceAnnounceList;
00259         QList <Uri> tier1;
00260         tier1.push_back (Uri::fromUnencoded ("http://tracker1.com"));
00261         referenceAnnounceList.push_back (tier1);
00262         CPPUNIT_ASSERT (torrent.announceList() == referenceAnnounceList);
00263     }
00264 
00266     void testAnnounceListParsingOneTierManyTrackers()
00267     {
00268         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00269             "13:announce-listll19:http://tracker1.com19:http://tracker2.com19:http://tracker3.com19:http://tracker4.comee"
00270             "4:infod6:lengthi6e4:name8:file.txt"
00271             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00272         Torrent torrent;
00273         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00274         CPPUNIT_ASSERT (loadedOk);
00275 
00276         Torrent::AnnounceList referenceAnnounceList;
00277         QList <Uri> tier1;
00278         tier1.push_back (Uri::fromUnencoded ("http://tracker1.com"));
00279         tier1.push_back (Uri::fromUnencoded ("http://tracker2.com"));
00280         tier1.push_back (Uri::fromUnencoded ("http://tracker3.com"));
00281         tier1.push_back (Uri::fromUnencoded ("http://tracker4.com"));
00282         referenceAnnounceList.push_back (tier1);
00283         CPPUNIT_ASSERT (torrent.announceList() == referenceAnnounceList);
00284     }
00285 
00287     void testAnnounceListParsingManyTiersOneTracker()
00288     {
00289         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00290             "13:announce-listll19:http://tracker1.comel19:http://tracker2.comel19:http://tracker3.comel19:http://tracker4.comee"
00291             "4:infod6:lengthi6e4:name8:file.txt"
00292             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00293         Torrent torrent;
00294         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00295         CPPUNIT_ASSERT (loadedOk);
00296 
00297         Torrent::AnnounceList referenceAnnounceList;
00298         QList <Uri> tier1;
00299         tier1.push_back (Uri::fromUnencoded ("http://tracker1.com"));
00300         referenceAnnounceList.push_back (tier1);
00301         QList <Uri> tier2;
00302         tier2.push_back (Uri::fromUnencoded ("http://tracker2.com"));
00303         referenceAnnounceList.push_back (tier2);
00304         QList <Uri> tier3;
00305         tier3.push_back (Uri::fromUnencoded ("http://tracker3.com"));
00306         referenceAnnounceList.push_back (tier3);
00307         QList <Uri> tier4;
00308         tier4.push_back (Uri::fromUnencoded ("http://tracker4.com"));
00309         referenceAnnounceList.push_back (tier4);
00310         CPPUNIT_ASSERT (torrent.announceList() == referenceAnnounceList);
00311     }
00312 
00314     void testAnnounceListParsingManyTiersManyTrackers()
00315     {
00316         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00317             "13:announce-listll19:http://tracker1.com19:http://tracker2.comel19:http://tracker3.com19:http://tracker4.comee"
00318             "4:infod6:lengthi6e4:name8:file.txt"
00319             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00320         Torrent torrent;
00321         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00322         CPPUNIT_ASSERT (loadedOk);
00323 
00324         Torrent::AnnounceList referenceAnnounceList;
00325         QList <Uri> tier1;
00326         tier1.push_back (Uri::fromUnencoded ("http://tracker1.com"));
00327         tier1.push_back (Uri::fromUnencoded ("http://tracker2.com"));
00328         referenceAnnounceList.push_back (tier1);
00329         QList <Uri> tier2;
00330         tier2.push_back (Uri::fromUnencoded ("http://tracker3.com"));
00331         tier2.push_back (Uri::fromUnencoded ("http://tracker4.com"));
00332         referenceAnnounceList.push_back (tier2);
00333         CPPUNIT_ASSERT (torrent.announceList() == referenceAnnounceList);
00334     }
00335 
00337     void testAnnounceListParsingOneTierNoTracker()
00338     {
00339         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00340             "13:announce-listllee"
00341             "4:infod6:lengthi6e4:name8:file.txt"
00342             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00343         Torrent torrent;
00344         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00345         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00346         CPPUNIT_ASSERT (torrent.announceList() == Torrent::AnnounceList());
00347     }
00348 
00350     void testAnnounceListParsingNestedTiers()
00351     {
00352         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00353             "13:announce-listll19:http://tracker1.coml19:http://tracker2.comeee"
00354             "4:infod6:lengthi6e4:name8:file.txt"
00355             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00356         Torrent torrent;
00357         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00358         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00359         CPPUNIT_ASSERT (torrent.announceList() == Torrent::AnnounceList());
00360     }
00361 
00363     void testLoadTorrentDataFileInfoMissingFileInfo()
00364     {
00365         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00366             "4:infod"
00367             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00368         Torrent torrent;
00369         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00370         CPPUNIT_ASSERT (!loadedOk);
00371     }
00372 
00374     void testLoadTorrentDataFileInfoMissingFileName()
00375     {
00376         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00377             "4:infod6:lengthi6e"
00378             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00379         Torrent torrent;
00380         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00381         CPPUNIT_ASSERT (!loadedOk);
00382     }
00383 
00385     void testLoadTorrentDataFileInfoMissingFileLength()
00386     {
00387         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00388             "4:infod4:name8:file.txt"
00389             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00390         Torrent torrent;
00391         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00392         CPPUNIT_ASSERT (!loadedOk);
00393     }
00394 
00396     void testLoadTorrentDataFileInfoNegativeFileLength()
00397     {
00398         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00399             "4:infod6:lengthi-22e4:name8:file.txt"
00400             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00401         Torrent torrent;
00402         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00403         CPPUNIT_ASSERT (!loadedOk);
00404     }
00405 
00407     void testLoadTorrentDataFileInfoZeroFileLength()
00408     {
00409         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00410             "4:infod6:lengthi0e4:name8:file.txt"
00411             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00412         Torrent torrent;
00413         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00414         CPPUNIT_ASSERT (!loadedOk);
00415     }
00416 
00418     void testLoadTorrentDataFileInfoValidChecksum()
00419     {
00420         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00421             "4:infod6:lengthi6e4:name8:file.txt6:md5sum32:7d435191a91ec22b4c9df11ad4769cac"
00422             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00423         Torrent torrent;
00424         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00425         CPPUNIT_ASSERT (loadedOk);
00426         CPPUNIT_ASSERT (torrent.files().size() == 1);
00427         CPPUNIT_ASSERT (torrent.files().front().checksum() ==
00428             Torrent::FileInfo::Checksum ("7d435191a91ec22b4c9df11ad4769cac"));
00429     }
00430 
00432     void testLoadTorrentDataFileInfoTooShortChecksum()
00433     {
00434         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00435             "4:infod6:lengthi6e4:name8:file.txt6:md5sum10:7d435191a9"
00436             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00437         Torrent torrent;
00438         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00439         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00440         CPPUNIT_ASSERT (torrent.files().size() == 1);
00441         CPPUNIT_ASSERT (torrent.files().front().checksum() ==
00442             Torrent::FileInfo::Checksum());
00443     }
00444 
00446     void testLoadTorrentDataFileInfoTooLongChecksum()
00447     {
00448         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00449             "4:infod6:lengthi6e4:name8:file.txt6:md5sum40:7d435191a91ec22b4c9df11ad4769cac6dg3ud6x"
00450             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00451         Torrent torrent;
00452         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00453         CPPUNIT_ASSERT (loadedOk); // True because this field is only optional
00454         CPPUNIT_ASSERT (torrent.files().size() == 1);
00455         CPPUNIT_ASSERT (torrent.files().front().checksum() ==
00456             Torrent::FileInfo::Checksum());
00457     }
00458 
00460     void testLoadTorrentDataMultipleFileInfoMissingDirectoryName()
00461     {
00462         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00463             "4:infod5:filesld6:lengthi100e4:pathl8:file.txteee"
00464             "6:md5sum32:7d435191a91ec22b4c9df11ad4769cac"
00465             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00466         Torrent torrent;
00467         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00468         CPPUNIT_ASSERT (!loadedOk);
00469     }
00470 
00472     void testLoadTorrentDataMultipleFileInfoMissingFiles()
00473     {
00474         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00475             "4:infod4:name4:root"
00476             "6:md5sum32:7d435191a91ec22b4c9df11ad4769cac"
00477             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00478         Torrent torrent;
00479         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00480         CPPUNIT_ASSERT (!loadedOk);
00481     }
00482 
00484     void testLoadTorrentDataMultipleFileInfoMissingFileLength()
00485     {
00486         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00487             "4:infod5:filesld4:pathl8:file.txteee4:name4:root"
00488             "6:md5sum32:7d435191a91ec22b4c9df11ad4769cac"
00489             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00490         Torrent torrent;
00491         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00492         CPPUNIT_ASSERT (!loadedOk);
00493     }
00494 
00496     void testLoadTorrentDataMultipleFileInfoMissingFilePath()
00497     {
00498         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00499             "4:infod5:filesld6:lengthi100eee4:name4:root"
00500             "6:md5sum32:7d435191a91ec22b4c9df11ad4769cac"
00501             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00502         Torrent torrent;
00503         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00504         CPPUNIT_ASSERT (!loadedOk);
00505     }
00506 
00508     void testFilePathParsingNoFiles()
00509     {
00510         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00511             "4:infod5:filesld6:lengthi100e4:pathleee4:name3:dir"
00512             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00513         Torrent torrent;
00514         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00515         CPPUNIT_ASSERT (!loadedOk);
00516     }
00517 
00519     void testFilePathParsingOnlyFile()
00520     {
00521         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00522             "4:infod5:filesld6:lengthi100e4:pathl8:file.txteee4:name4:root"
00523             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00524         Torrent torrent;
00525         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00526         CPPUNIT_ASSERT (loadedOk);
00527         Torrent::FileInfoList fileInfoList = torrent.files();
00528         CPPUNIT_ASSERT (fileInfoList.size() == 1);
00529         Torrent::FileInfo fileInfo = fileInfoList.front();
00530         CPPUNIT_ASSERT (fileInfo.path() == "root/file.txt");
00531     }
00532 
00534     void testFilePathParsingOneDirectory()
00535     {
00536         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00537             "4:infod5:filesld6:lengthi100e4:pathl4:dir18:file.txteee4:name4:root"
00538             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00539         Torrent torrent;
00540         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00541         CPPUNIT_ASSERT (loadedOk);
00542         Torrent::FileInfoList fileInfoList = torrent.files();
00543         CPPUNIT_ASSERT (fileInfoList.size() == 1);
00544         Torrent::FileInfo fileInfo = fileInfoList.front();
00545         CPPUNIT_ASSERT (fileInfo.path() == "root/dir1/file.txt");
00546     }
00547 
00549     void testFilePathParsingMoreDirectories()
00550     {
00551         QByteArray rawTorrentData ("d8:announce18:http://tracker.com"
00552             "4:infod5:filesld6:lengthi100e4:pathl4:dir14:dir24:dir38:file.txteee4:name4:root"
00553             "12:piece lengthi32768e6:pieces20:XXXXXXXXXXXXXXXXXXXXee");
00554         Torrent torrent;
00555         bool loadedOk = TorrentParser::parseAndLoadTorrent (rawTorrentData, torrent);
00556         CPPUNIT_ASSERT (loadedOk);
00557         Torrent::FileInfoList fileInfoList = torrent.files();
00558         CPPUNIT_ASSERT (fileInfoList.size() == 1);
00559         Torrent::FileInfo fileInfo = fileInfoList.front();
00560         CPPUNIT_ASSERT (fileInfo.path() == "root/dir1/dir2/dir3/file.txt");
00561     }
00562 
00564     void testLoadTorrentDataSimpleTorrent()
00565     {
00566         QString torrentFileName ("Protocols/BitTorrent/Torrents/Testing/Samples/sample.torrent");
00567         Torrent torrent;
00568         bool loadedOk = loadTorrentData (torrentFileName, torrent);
00569         CPPUNIT_ASSERT (loadedOk);
00570 
00571         CPPUNIT_ASSERT (torrent.announce() == Uri::fromUnencoded ("http://tracker.calitko.org/torrents.php?passkey=d7c034325e7274bb2s346c6fc5b71307"));
00572         Torrent::AnnounceList referenceAnnounceList;
00573         CPPUNIT_ASSERT (torrent.announceList() == referenceAnnounceList);
00574         CPPUNIT_ASSERT (torrent.createdBy() == "BitComet/0.54");
00575         CPPUNIT_ASSERT (torrent.creationDate().toTime_t() == 1135459991);
00576         CPPUNIT_ASSERT (torrent.pieceLength() == 5282);
00577         CPPUNIT_ASSERT (sumOfAllPiecesLength (torrent.pieces()) == 6540);
00578         CPPUNIT_ASSERT (torrent.pieces().size() == 327); // 6540 / 20
00579         CPPUNIT_ASSERT (!torrent.isPrivate());
00580         Torrent::FileInfoList fileInfoList = torrent.files();
00581         CPPUNIT_ASSERT (fileInfoList.size() == 2);
00582 
00583         Torrent::FileInfo fileInfo = fileInfoList.front();
00584         CPPUNIT_ASSERT (fileInfo.path() == "Calitko/Calitko_source.zip");
00585         CPPUNIT_ASSERT (fileInfo.length() == 7618688);
00586         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00587         fileInfoList.pop_front();
00588         fileInfo = fileInfoList.front();
00589         CPPUNIT_ASSERT (fileInfo.path() == "Calitko/Calitko_doc.zip");
00590         CPPUNIT_ASSERT (fileInfo.length() == 13521024);
00591         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00592         fileInfoList.pop_front();
00593     }
00594 
00596     void testLoadTorrentDataMoreComplexTorrent()
00597     {
00598         QString torrentFileName ("Protocols/BitTorrent/Torrents/Testing/Samples/sample2.torrent");
00599         Torrent torrent;
00600         bool loadedOk = loadTorrentData (torrentFileName, torrent);
00601         CPPUNIT_ASSERT (loadedOk);
00602 
00603         CPPUNIT_ASSERT (torrent.announce() == Uri::fromUnencoded ("http://tracker1.com"));
00604         Torrent::AnnounceList referenceAnnounceList;
00605         QList <Uri> tier1;
00606         tier1.push_back (Uri::fromUnencoded ("http://tracker1.com"));
00607         tier1.push_back (Uri::fromUnencoded ("http://tracker2.com"));
00608         tier1.push_back (Uri::fromUnencoded ("http://tracker3.com"));
00609         referenceAnnounceList.push_back (tier1);
00610         CPPUNIT_ASSERT (torrent.announceList() == referenceAnnounceList);
00611         CPPUNIT_ASSERT (torrent.createdBy() == "KTorrent 2.1.4");
00612         CPPUNIT_ASSERT (torrent.comment() == "Just a testing comment for my testing torrent.");
00613         CPPUNIT_ASSERT (torrent.creationDate().toTime_t() == 1182163222);
00614         CPPUNIT_ASSERT (torrent.pieceLength() == 262144);
00615         CPPUNIT_ASSERT (sumOfAllPiecesLength (torrent.pieces()) == 20);
00616         CPPUNIT_ASSERT (torrent.pieces().size() == 1);
00617         CPPUNIT_ASSERT (!torrent.isPrivate());
00618         Torrent::FileInfoList fileInfoList = torrent.files();
00619         CPPUNIT_ASSERT (fileInfoList.size() == 4);
00620 
00621         Torrent::FileInfo fileInfo = fileInfoList.front();
00622         CPPUNIT_ASSERT (fileInfo.path() == "root_dir/file1.txt");
00623         CPPUNIT_ASSERT (fileInfo.length() == 3184);
00624         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00625         fileInfoList.pop_front();
00626         fileInfo = fileInfoList.front();
00627         CPPUNIT_ASSERT (fileInfo.path() == "root_dir/file2.txt");
00628         CPPUNIT_ASSERT (fileInfo.length() == 2878);
00629         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00630         fileInfoList.pop_front();
00631         fileInfo = fileInfoList.front();
00632         CPPUNIT_ASSERT (fileInfo.path() == "root_dir/file3.txt");
00633         CPPUNIT_ASSERT (fileInfo.length() == 3412);
00634         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00635         fileInfoList.pop_front();
00636         fileInfo = fileInfoList.front();
00637         CPPUNIT_ASSERT (fileInfo.path() == "root_dir/file4.txt");
00638         CPPUNIT_ASSERT (fileInfo.length() == 2804);
00639         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00640         fileInfoList.pop_front();
00641     }
00642 
00644     void testLoadTorrentDataTorrentWithEverything()
00645     {
00646         QString torrentFileName ("Protocols/BitTorrent/Torrents/Testing/Samples/sample3.torrent");
00647         Torrent torrent;
00648         bool loadedOk = loadTorrentData (torrentFileName, torrent);
00649         CPPUNIT_ASSERT (loadedOk);
00650 
00651         CPPUNIT_ASSERT (torrent.announce() == Uri::fromUnencoded ("http://tracker1.com"));
00652         Torrent::AnnounceList referenceAnnounceList;
00653         QList <Uri> tier1;
00654         tier1.push_back (Uri::fromUnencoded ("http://tracker1.com"));
00655         tier1.push_back (Uri::fromUnencoded ("http://tracker2.com"));
00656         referenceAnnounceList.push_back (tier1);
00657         CPPUNIT_ASSERT (torrent.announceList() == referenceAnnounceList);
00658         CPPUNIT_ASSERT (torrent.createdBy() == "KTorrent 2.1.4");
00659         CPPUNIT_ASSERT (torrent.comment() == "This torrent should contain \"everything\".");
00660         CPPUNIT_ASSERT (torrent.creationDate().toTime_t() == 1182416886);
00661         CPPUNIT_ASSERT (torrent.pieceLength() == 65536);
00662         CPPUNIT_ASSERT (sumOfAllPiecesLength (torrent.pieces()) == 20);
00663         CPPUNIT_ASSERT (torrent.pieces().size() == 1);
00664         CPPUNIT_ASSERT (torrent.isPrivate());
00665         Torrent::FileInfoList fileInfoList = torrent.files();
00666         CPPUNIT_ASSERT (fileInfoList.size() == 8);
00667 
00668         Torrent::FileInfo fileInfo = fileInfoList.front();
00669         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/file1.txt");
00670         CPPUNIT_ASSERT (fileInfo.length() == 3184);
00671         CPPUNIT_ASSERT (fileInfo.checksum() ==
00672             Torrent::FileInfo::Checksum ("687bef2cce996c2c99aab769fe9d9386"));
00673         fileInfoList.pop_front();
00674         fileInfo = fileInfoList.front();
00675         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/file2.txt");
00676         CPPUNIT_ASSERT (fileInfo.length() == 2878);
00677         CPPUNIT_ASSERT (fileInfo.checksum() ==
00678             Torrent::FileInfo::Checksum ("1d003904ec8abef451ae80531f95ea47"));
00679         fileInfoList.pop_front();
00680         fileInfo = fileInfoList.front();
00681         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/dir1/file3.txt");
00682         CPPUNIT_ASSERT (fileInfo.length() == 3184);
00683         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00684         fileInfoList.pop_front();
00685         fileInfo = fileInfoList.front();
00686         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/dir1/file4.txt");
00687         CPPUNIT_ASSERT (fileInfo.length() == 2878);
00688         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00689         fileInfoList.pop_front();
00690         fileInfo = fileInfoList.front();
00691         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/dir2/file5.txt");
00692         CPPUNIT_ASSERT (fileInfo.length() == 3412);
00693         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00694         fileInfoList.pop_front();
00695         fileInfo = fileInfoList.front();
00696         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/dir2/file6.txt");
00697         CPPUNIT_ASSERT (fileInfo.length() == 2804);
00698         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00699         fileInfoList.pop_front();
00700         fileInfo = fileInfoList.front();
00701         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/dir2/dir3/file7.txt");
00702         CPPUNIT_ASSERT (fileInfo.length() == 3412);
00703         CPPUNIT_ASSERT (fileInfo.checksum() ==
00704             Torrent::FileInfo::Checksum ("2a1aa6c9854517d894f05da495f0414d"));
00705         fileInfoList.pop_front();
00706         fileInfo = fileInfoList.front();
00707         CPPUNIT_ASSERT (fileInfo.path() == "root_dir2/dir2/dir3/file8.txt");
00708         CPPUNIT_ASSERT (fileInfo.length() == 2804);
00709         CPPUNIT_ASSERT (fileInfo.checksum() ==
00710             Torrent::FileInfo::Checksum ("14d8b9aeb391c2c34f61bdf18bac77db"));
00711         fileInfoList.pop_front();
00712     }
00713 
00715     void testLoadTorrentDataMinimalTorrent()
00716     {
00717         QString torrentFileName ("Protocols/BitTorrent/Torrents/Testing/Samples/minimal.torrent");
00718         Torrent torrent;
00719         bool loadedOk = loadTorrentData (torrentFileName, torrent);
00720         CPPUNIT_ASSERT (loadedOk);
00721 
00722         CPPUNIT_ASSERT (torrent.announce() == Uri::fromUnencoded ("http://tracker.com"));
00723         CPPUNIT_ASSERT (torrent.announceList() == Torrent::AnnounceList());
00724         CPPUNIT_ASSERT (torrent.createdBy() == QString());
00725         CPPUNIT_ASSERT (torrent.creationDate() == QDateTime());
00726         CPPUNIT_ASSERT (torrent.pieceLength() == 32768);
00727         CPPUNIT_ASSERT (sumOfAllPiecesLength (torrent.pieces()) == 20);
00728         CPPUNIT_ASSERT (torrent.pieces().size() == 1);
00729         CPPUNIT_ASSERT (!torrent.isPrivate());
00730         CPPUNIT_ASSERT (torrent.files().size() == 1);
00731 
00732         Torrent::FileInfo fileInfo = torrent.files().front();
00733         CPPUNIT_ASSERT (fileInfo.path() == "file.txt");
00734         CPPUNIT_ASSERT (fileInfo.length() == 6);
00735         CPPUNIT_ASSERT (fileInfo.checksum() == Torrent::FileInfo::Checksum());
00736     }
00737 
00739     void testLoadTorrentDataEmptyTorrent()
00740     {
00741         QString torrentFileName ("Protocols/BitTorrent/Torrents/Testing/Samples/empty.torrent");
00742         Torrent torrent;
00743         bool loadedOk = loadTorrentData (torrentFileName, torrent);
00744         CPPUNIT_ASSERT (!loadedOk);
00745 
00746         CPPUNIT_ASSERT (torrent.announce() == Uri());
00747         CPPUNIT_ASSERT (torrent.announceList() == Torrent::AnnounceList());
00748         CPPUNIT_ASSERT (torrent.createdBy() == QString());
00749         CPPUNIT_ASSERT (torrent.creationDate() == QDateTime());
00750         CPPUNIT_ASSERT (torrent.pieceLength() == 0);
00751         CPPUNIT_ASSERT (sumOfAllPiecesLength (torrent.pieces()) == 0);
00752         CPPUNIT_ASSERT (torrent.pieces().size() == 0);
00753         CPPUNIT_ASSERT (!torrent.isPrivate());
00754         CPPUNIT_ASSERT (torrent.files().empty());
00755     }
00756 };
00757 
00758 CPPUNIT_TEST_SUITE_REGISTRATION(TorrentParserTest);
00759 
00760 } // namespace Testing
00761 } // namespace Torrents
00762 } // namespace BitTorrent
00763 } // namespace Protocols