File indexing completed on 2025-01-05 04:37:15
0001 #ifndef QT_GUI_LIB 0002 #define QT_GUI_LIB 0003 #endif 0004 0005 #include <ctime> 0006 0007 #include <QEventLoop> 0008 #include <QLocale> 0009 #include <QtTest> 0010 0011 #include "testlib/dummytorrentcreator.h" 0012 #include <diskio/chunkmanager.h> 0013 #include <download/downloader.h> 0014 #include <download/streamingchunkselector.h> 0015 #include <interfaces/piecedownloader.h> 0016 #include <torrent/torrentcontrol.h> 0017 #include <util/bitset.h> 0018 #include <util/error.h> 0019 #include <util/fileops.h> 0020 #include <util/functions.h> 0021 #include <util/log.h> 0022 0023 using namespace bt; 0024 0025 const bt::Uint64 TEST_FILE_SIZE = 15 * 1024 * 1024; 0026 0027 class DummyDownloader : public PieceDownloader 0028 { 0029 public: 0030 ~DummyDownloader() override 0031 { 0032 } 0033 0034 bool canAddRequest() const override 0035 { 0036 return true; 0037 } 0038 void cancel(const bt::Request &) override 0039 { 0040 } 0041 void cancelAll() override 0042 { 0043 } 0044 bool canDownloadChunk() const override 0045 { 0046 return getNumGrabbed() == 0; 0047 } 0048 void download(const bt::Request &) override 0049 { 0050 } 0051 void checkTimeouts() override 0052 { 0053 } 0054 Uint32 getDownloadRate() const override 0055 { 0056 return 0; 0057 } 0058 QString getName() const override 0059 { 0060 return "foobar"; 0061 } 0062 bool isChoked() const override 0063 { 0064 return false; 0065 } 0066 }; 0067 0068 class ExtendedStreamingChunkSelector : public bt::StreamingChunkSelector 0069 { 0070 public: 0071 ExtendedStreamingChunkSelector() 0072 { 0073 } 0074 ~ExtendedStreamingChunkSelector() override 0075 { 0076 } 0077 0078 void markDownloaded(Uint32 i) 0079 { 0080 cman->chunkDownloaded(i); 0081 } 0082 0083 Downloader *downloader() 0084 { 0085 return downer; 0086 } 0087 }; 0088 0089 class StreamingChunkSelectorTest : public QEventLoop 0090 { 0091 Q_OBJECT 0092 0093 public: 0094 StreamingChunkSelectorTest() 0095 { 0096 } 0097 0098 StreamingChunkSelectorTest(QObject *parent) 0099 : QEventLoop(parent) 0100 { 0101 } 0102 0103 private Q_SLOTS: 0104 void initTestCase() 0105 { 0106 QLocale::setDefault(QLocale("main")); 0107 bt::InitLibKTorrent(); 0108 bt::InitLog("streamingchunkselectortest.log", false, true); 0109 } 0110 0111 void testSimple() 0112 { 0113 DummyTorrentCreator creator; 0114 bt::TorrentControl tc; 0115 QVERIFY(creator.createSingleFileTorrent(TEST_FILE_SIZE, "test.avi")); 0116 0117 Out(SYS_GEN | LOG_DEBUG) << "Created " << creator.torrentPath() << endl; 0118 try { 0119 tc.init(nullptr, bt::LoadFile(creator.torrentPath()), creator.tempPath() + "tor0", creator.tempPath() + "data/"); 0120 tc.createFiles(); 0121 } catch (bt::Error &err) { 0122 Out(SYS_GEN | LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl; 0123 QFAIL("Torrent load failure"); 0124 } 0125 0126 ExtendedStreamingChunkSelector *csel = new ExtendedStreamingChunkSelector(); 0127 tc.setChunkSelector(csel); 0128 QVERIFY(csel != nullptr); 0129 csel->setSequentialRange(0, 50); 0130 0131 for (Uint32 i = 0; i < 50; i++) { 0132 DummyDownloader dd; 0133 Uint32 selected = 0xFFFFFFFF; 0134 QVERIFY(csel->select(&dd, selected)); 0135 Out(SYS_GEN) << "i = " << i << ", selected = " << selected << endl; 0136 QVERIFY(selected == i); 0137 csel->markDownloaded(i); 0138 } 0139 0140 // cleanup 0141 tc.setChunkSelector(nullptr); 0142 } 0143 0144 void testCriticalChunkSpread() 0145 { 0146 DummyTorrentCreator creator; 0147 bt::TorrentControl tc; 0148 QVERIFY(creator.createSingleFileTorrent(2 * TEST_FILE_SIZE, "test2.avi")); 0149 0150 Out(SYS_GEN | LOG_DEBUG) << "Created " << creator.torrentPath() << endl; 0151 try { 0152 tc.init(nullptr, bt::LoadFile(creator.torrentPath()), creator.tempPath() + "tor0", creator.tempPath() + "data/"); 0153 tc.createFiles(); 0154 } catch (bt::Error &err) { 0155 Out(SYS_GEN | LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl; 0156 QFAIL("Torrent load failure"); 0157 } 0158 0159 ExtendedStreamingChunkSelector *csel = new ExtendedStreamingChunkSelector(); 0160 tc.setChunkSelector(csel); 0161 QVERIFY(csel != nullptr); 0162 Downloader *downer = csel->downloader(); 0163 QVERIFY(downer != nullptr); 0164 0165 // Check that critical chunks are spread over multiple peers 0166 csel->setSequentialRange(20, 60); 0167 DummyDownloader dd[32]; 0168 for (Uint32 i = 0; i < 32; i++) { 0169 downer->addPieceDownloader(&dd[i]); 0170 } 0171 0172 // Check the spread of the downloaders 0173 downer->update(); 0174 for (Uint32 i = 20; i < csel->criticialWindowSize(); i++) { 0175 QVERIFY(downer->downloading(i)); 0176 QVERIFY(downer->download(i)->getNumDownloaders() == 32 / csel->criticialWindowSize()); 0177 } 0178 0179 for (Uint32 i = 0; i < 32; i++) { 0180 QVERIFY(dd[i].getNumGrabbed() == 1); 0181 } 0182 0183 for (Uint32 i = 0; i < 32; i++) { 0184 downer->removePieceDownloader(&dd[i]); 0185 } 0186 // cleanup 0187 tc.setChunkSelector(nullptr); 0188 } 0189 }; 0190 0191 QTEST_MAIN(StreamingChunkSelectorTest) 0192 0193 #include "streamingchunkselectortest.moc"