10
#include <util/error.h>
11
#include <util/sha1hashgen.h>
12
#include <testlib/dummytorrentcreator.h>
13
#include <torrent/torrentcontrol.h>
14
#include <torrent/torrentfilestream.h>
15
#include <interfaces/queuemanagerinterface.h>
21
const bt::Uint32 TEST_FILE_SIZE = 5*1024*1024;
23
class TorrentFileStreamTest : public QEventLoop, public bt::QueueManagerInterface
27
TorrentFileStreamTest(QObject* parent = 0) : QEventLoop(parent)
31
virtual bool alreadyLoaded(const bt::SHA1Hash& ih) const
37
virtual void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk)
46
KGlobal::setLocale(new KLocale("main"));
47
bt::InitLog("torrentfilestreamtest.log",false,false);
48
QVERIFY(creator.createSingleFileTorrent(TEST_FILE_SIZE,"test.avi"));
50
Out(SYS_GEN|LOG_DEBUG) << "Created " << creator.torrentPath() << endl;
53
tc.init(this,creator.torrentPath(),creator.tempPath() + "tor0",creator.tempPath() + "data/");
55
QVERIFY(tc.hasExistingFiles());
56
tc.startDataCheck(false);
59
processEvents(AllEvents,1000);
61
while (tc.getStats().status == bt::CHECKING_DATA);
62
QVERIFY(tc.getStats().completed);
64
catch (bt::Error & err)
66
Out(SYS_GEN|LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl;
67
QFAIL("Torrent load failure");
73
void cleanupTestCase()
79
Out(SYS_GEN|LOG_DEBUG) << "Begin: testSimple() " << endl;
80
bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
82
QVERIFY(!stream->open(QIODevice::ReadWrite));
83
QVERIFY(stream->open(QIODevice::ReadOnly));
84
// Simple test read per chunk and verify if it works
85
QByteArray tmp(tc.getStats().chunk_size,0);
86
bt::Uint64 written = 0;
88
while (written < TEST_FILE_SIZE)
90
qint64 ret = stream->read(tmp.data(),tc.getStats().chunk_size);
91
QVERIFY(ret == tc.getStats().chunk_size);
92
written += tc.getStats().chunk_size;
95
bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)tmp.data(),tmp.size());
96
QVERIFY(hash == tc.getTorrent().getHash(idx));
101
Out(SYS_GEN|LOG_DEBUG) << "End: testSimple() " << endl;
106
Out(SYS_GEN|LOG_DEBUG) << "Begin: testSeek() " << endl;
107
bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
109
QVERIFY(!stream->open(QIODevice::ReadWrite));
110
QVERIFY(stream->open(QIODevice::ReadOnly));
111
// Simple test read per chunk and seek somewhat
112
bt::Uint32 chunk_size = tc.getStats().chunk_size;
113
QByteArray tmp(chunk_size,0);
114
bt::Uint64 written = 0;
116
while (written < TEST_FILE_SIZE)
118
// Chunk size of last chunk can be smaller
119
if (idx == tc.getStats().total_chunks - 1)
121
chunk_size = tc.getStats().chunk_size % tc.getStats().total_bytes;
123
chunk_size = tc.getStats().chunk_size;
126
// Lets read in two times, first at the back and then at the front
127
qint64 split = qrand() % chunk_size;
129
split = qrand() % chunk_size;
131
QVERIFY(stream->seek(idx * tc.getStats().chunk_size + split));
132
qint64 ret = stream->read(tmp.data() + split,chunk_size - split);
133
QVERIFY(ret == (chunk_size - split));
136
QVERIFY(stream->seek(idx * tc.getStats().chunk_size));
137
ret = stream->read(tmp.data(),split);
138
QVERIFY(ret == split);
142
bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)tmp.data(),tmp.size());
143
QVERIFY(hash == tc.getTorrent().getHash(idx));
148
Out(SYS_GEN|LOG_DEBUG) << "End: testSeek() " << endl;
151
void testRandomAccess()
153
Out(SYS_GEN|LOG_DEBUG) << "Begin: testRandomAccess() " << endl;
154
bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
156
QVERIFY(!stream->open(QIODevice::ReadWrite));
157
QVERIFY(stream->open(QIODevice::ReadOnly));
159
// Read an area of around 5 chunks in at a random location
160
// And verify the 3 middle chunks
161
bt::Uint64 range_size = tc.getStats().chunk_size * 5;
162
qint64 off = ((qrand() % 100) / 100.0) * (tc.getStats().total_bytes - range_size);
163
QVERIFY(stream->seek(off));
165
Out(SYS_GEN|LOG_DEBUG) << "Reading random range" << endl;
166
Out(SYS_GEN|LOG_DEBUG) << "range_size = " << range_size << endl;
167
Out(SYS_GEN|LOG_DEBUG) << "off = " << off << endl;
169
QByteArray range(range_size,0);
170
qint64 bytes_read = 0;
171
while (bytes_read < range_size)
173
qint64 ret = stream->read(range.data() + bytes_read,range_size - bytes_read);
174
Out(SYS_GEN|LOG_DEBUG) << "ret = " << ret << endl;
175
Out(SYS_GEN|LOG_DEBUG) << "read = " << bytes_read << endl;
181
QFile fptr(stream->path());
182
QVERIFY(fptr.open(QIODevice::ReadOnly));
183
QByteArray tmp(range_size,0);
185
QVERIFY(fptr.read(tmp.data(),range_size) == range_size);
186
QVERIFY(tmp == range);
189
QVERIFY(bytes_read == range_size);
191
// Calculate the offset of the first chunk in range
192
qint64 chunk_idx = off / tc.getStats().chunk_size;
193
if (off % tc.getStats().chunk_size != 0)
195
qint64 chunk_off = chunk_idx * tc.getStats().chunk_size - off;
197
Out(SYS_GEN|LOG_DEBUG) << "chunk_idx = " << chunk_idx << endl;
198
Out(SYS_GEN|LOG_DEBUG) << "chunk_off = " << chunk_off << endl;
203
for (int i = 0;i < 3;i++)
205
bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)range.data() + chunk_off,tc.getStats().chunk_size);
207
Out(SYS_GEN|LOG_DEBUG) << "chash = " << hash.toString() << endl;
208
Out(SYS_GEN|LOG_DEBUG) << "whash = " << tc.getTorrent().getHash(chunk_idx).toString() << endl;
209
QVERIFY(hash == tc.getTorrent().getHash(chunk_idx));
211
chunk_off += tc.getStats().chunk_size;
215
Out(SYS_GEN|LOG_DEBUG) << "End: testRandomAccess() " << endl;
220
Out(SYS_GEN|LOG_DEBUG) << "Begin: testMultiSeek() " << endl;
221
bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
223
QVERIFY(!stream->open(QIODevice::ReadWrite));
224
QVERIFY(stream->open(QIODevice::ReadOnly));
226
QFile fptr(stream->path());
227
QVERIFY(fptr.open(QIODevice::ReadOnly));
228
for (int i = 0;i < 20;i++)
230
qint64 off = qrand() % (TEST_FILE_SIZE - 100);
231
// Seek to a random location
232
QVERIFY(stream->seek(off));
233
QByteArray tmp(100,0);
234
QVERIFY(stream->read(tmp.data(),100) == 100);
237
QByteArray tmp2(100,0);
239
QVERIFY(fptr.read(tmp2.data(),100) == 100);
240
QVERIFY(tmp == tmp2);
244
Out(SYS_GEN|LOG_DEBUG) << "End: testMultiSeek() " << endl;
247
void testStreamingCreate()
249
bt::TorrentFileStream::Ptr a = tc.createTorrentFileStream(0,true,this);
251
bt::TorrentFileStream::Ptr b = tc.createTorrentFileStream(0,true,this);
254
b = tc.createTorrentFileStream(0,true,this);
259
DummyTorrentCreator creator;
260
bt::TorrentControl tc;
263
QTEST_MAIN(TorrentFileStreamTest)
265
#include "torrentfilestreamtest.moc"
b'\\ No newline at end of file'