~ubuntu-branches/ubuntu/oneiric/libktorrent/oneiric

« back to all changes in this revision

Viewing changes to src/torrent/tests/torrentfilestreamtest.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Modestas Vainius
  • Date: 2011-05-26 00:33:38 UTC
  • mfrom: (5.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110526003338-2r4zwyzn8bovsxay
Tags: 1.1.1-2
Release to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#define QT_GUI_LIB
 
2
 
 
3
#include <QtTest>
 
4
#include <QObject>
 
5
#include <KGlobal>
 
6
#include <KLocale>
 
7
#include <unistd.h>
 
8
#include <time.h>
 
9
#include <util/log.h>
 
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>
 
16
 
 
17
 
 
18
 
 
19
using namespace bt;
 
20
 
 
21
const bt::Uint32 TEST_FILE_SIZE = 5*1024*1024;
 
22
 
 
23
class TorrentFileStreamTest : public QEventLoop, public bt::QueueManagerInterface
 
24
{
 
25
        Q_OBJECT
 
26
public:
 
27
        TorrentFileStreamTest(QObject* parent = 0) : QEventLoop(parent)
 
28
        {
 
29
        }
 
30
        
 
31
        virtual bool alreadyLoaded(const bt::SHA1Hash& ih) const
 
32
        {
 
33
                Q_UNUSED(ih);
 
34
                return false;
 
35
        }
 
36
        
 
37
        virtual void mergeAnnounceList(const bt::SHA1Hash& ih, const bt::TrackerTier* trk)
 
38
        {
 
39
                Q_UNUSED(ih);
 
40
                Q_UNUSED(trk);
 
41
        }
 
42
        
 
43
private slots:
 
44
        void initTestCase()
 
45
        {
 
46
                KGlobal::setLocale(new KLocale("main"));
 
47
                bt::InitLog("torrentfilestreamtest.log",false,false);
 
48
                QVERIFY(creator.createSingleFileTorrent(TEST_FILE_SIZE,"test.avi"));
 
49
 
 
50
                Out(SYS_GEN|LOG_DEBUG) << "Created " << creator.torrentPath() << endl;
 
51
                try
 
52
                {
 
53
                        tc.init(this,creator.torrentPath(),creator.tempPath() + "tor0",creator.tempPath() + "data/");
 
54
                        tc.createFiles();
 
55
                        QVERIFY(tc.hasExistingFiles());
 
56
                        tc.startDataCheck(false);
 
57
                        do
 
58
                        {
 
59
                                processEvents(AllEvents,1000);
 
60
                        }
 
61
                        while (tc.getStats().status == bt::CHECKING_DATA);
 
62
                        QVERIFY(tc.getStats().completed);
 
63
                }
 
64
                catch (bt::Error & err)
 
65
                {
 
66
                        Out(SYS_GEN|LOG_DEBUG) << "Failed to load torrent: " << creator.torrentPath() << endl;
 
67
                        QFAIL("Torrent load failure");
 
68
                }
 
69
                
 
70
                qsrand(time(0));
 
71
        }
 
72
        
 
73
        void cleanupTestCase()
 
74
        {
 
75
        }
 
76
        
 
77
        void testSimple()
 
78
        {
 
79
                Out(SYS_GEN|LOG_DEBUG) << "Begin: testSimple() " << endl;
 
80
                bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
 
81
                QVERIFY(stream);
 
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;
 
87
                bt::Uint32 idx = 0;
 
88
                while (written < TEST_FILE_SIZE)
 
89
                {
 
90
                        qint64 ret = stream->read(tmp.data(),tc.getStats().chunk_size);
 
91
                        QVERIFY(ret == tc.getStats().chunk_size);
 
92
                        written += tc.getStats().chunk_size;
 
93
                        
 
94
                        // Verify the hash
 
95
                        bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)tmp.data(),tmp.size());
 
96
                        QVERIFY(hash == tc.getTorrent().getHash(idx));
 
97
                        idx++;
 
98
                }
 
99
                
 
100
                stream->close();
 
101
                Out(SYS_GEN|LOG_DEBUG) << "End: testSimple() " << endl;
 
102
        }
 
103
        
 
104
        void testSeek()
 
105
        {
 
106
                Out(SYS_GEN|LOG_DEBUG) << "Begin: testSeek() " << endl;
 
107
                bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
 
108
                QVERIFY(stream);
 
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;
 
115
                bt::Uint32 idx = 0;
 
116
                while (written < TEST_FILE_SIZE)
 
117
                {
 
118
                        // Chunk size of last chunk can be smaller
 
119
                        if (idx == tc.getStats().total_chunks - 1)
 
120
                        {
 
121
                                chunk_size = tc.getStats().chunk_size % tc.getStats().total_bytes;
 
122
                                if (chunk_size == 0)
 
123
                                        chunk_size = tc.getStats().chunk_size;
 
124
                        }
 
125
                        
 
126
                        // Lets read in two times, first at the back and then at the front
 
127
                        qint64 split = qrand() % chunk_size;
 
128
                        while (split == 0)
 
129
                                split = qrand() % chunk_size;
 
130
                        
 
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));
 
134
                        written += ret;
 
135
                        
 
136
                        QVERIFY(stream->seek(idx * tc.getStats().chunk_size));
 
137
                        ret = stream->read(tmp.data(),split);
 
138
                        QVERIFY(ret == split);
 
139
                        written += ret;
 
140
                        
 
141
                        // Verify the hash
 
142
                        bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)tmp.data(),tmp.size());
 
143
                        QVERIFY(hash == tc.getTorrent().getHash(idx));
 
144
                        idx++;
 
145
                }
 
146
                
 
147
                stream->close();
 
148
                Out(SYS_GEN|LOG_DEBUG) << "End: testSeek() " << endl;
 
149
        }
 
150
        
 
151
        void testRandomAccess()
 
152
        {
 
153
                Out(SYS_GEN|LOG_DEBUG) << "Begin: testRandomAccess() " << endl;
 
154
                bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
 
155
                QVERIFY(stream);
 
156
                QVERIFY(!stream->open(QIODevice::ReadWrite));
 
157
                QVERIFY(stream->open(QIODevice::ReadOnly));
 
158
                
 
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));
 
164
                
 
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;
 
168
                
 
169
                QByteArray range(range_size,0);
 
170
                qint64 bytes_read = 0;
 
171
                while (bytes_read < range_size)
 
172
                {
 
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;
 
176
                        QVERIFY(ret > 0);
 
177
                        bytes_read += ret;
 
178
                }
 
179
                
 
180
                {
 
181
                        QFile fptr(stream->path());
 
182
                        QVERIFY(fptr.open(QIODevice::ReadOnly));
 
183
                        QByteArray tmp(range_size,0);
 
184
                        fptr.seek(off);
 
185
                        QVERIFY(fptr.read(tmp.data(),range_size) == range_size);
 
186
                        QVERIFY(tmp == range);
 
187
                }
 
188
                
 
189
                QVERIFY(bytes_read == range_size);
 
190
                
 
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)
 
194
                        chunk_idx++;
 
195
                qint64 chunk_off = chunk_idx * tc.getStats().chunk_size - off;
 
196
                
 
197
                Out(SYS_GEN|LOG_DEBUG) << "chunk_idx = " << chunk_idx << endl;
 
198
                Out(SYS_GEN|LOG_DEBUG) << "chunk_off = " << chunk_off << endl;
 
199
                
 
200
                
 
201
                
 
202
                // Verify the hashes
 
203
                for (int i = 0;i < 3;i++)
 
204
                {
 
205
                        bt::SHA1Hash hash = bt::SHA1Hash::generate((const bt::Uint8*)range.data() + chunk_off,tc.getStats().chunk_size);
 
206
                        
 
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));
 
210
                        chunk_idx++;
 
211
                        chunk_off += tc.getStats().chunk_size;
 
212
                }
 
213
                
 
214
                stream->close();
 
215
                Out(SYS_GEN|LOG_DEBUG) << "End: testRandomAccess() " << endl;
 
216
        }
 
217
        
 
218
        void testMultiSeek()
 
219
        {
 
220
                Out(SYS_GEN|LOG_DEBUG) << "Begin: testMultiSeek() " << endl;
 
221
                bt::TorrentFileStream::Ptr stream = tc.createTorrentFileStream(0,false,this);
 
222
                QVERIFY(stream);
 
223
                QVERIFY(!stream->open(QIODevice::ReadWrite));
 
224
                QVERIFY(stream->open(QIODevice::ReadOnly));
 
225
                
 
226
                QFile fptr(stream->path());
 
227
                QVERIFY(fptr.open(QIODevice::ReadOnly));
 
228
                for (int i = 0;i < 20;i++)
 
229
                {
 
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);
 
235
                
 
236
                        // Verify those
 
237
                        QByteArray tmp2(100,0);
 
238
                        fptr.seek(off);
 
239
                        QVERIFY(fptr.read(tmp2.data(),100) == 100);
 
240
                        QVERIFY(tmp == tmp2);
 
241
                }
 
242
                
 
243
                stream->close();
 
244
                Out(SYS_GEN|LOG_DEBUG) << "End: testMultiSeek() " << endl;
 
245
        }
 
246
        
 
247
        void testStreamingCreate()
 
248
        {
 
249
                bt::TorrentFileStream::Ptr a = tc.createTorrentFileStream(0,true,this);
 
250
                QVERIFY(a);
 
251
                bt::TorrentFileStream::Ptr b = tc.createTorrentFileStream(0,true,this);
 
252
                QVERIFY(!b);
 
253
                a.clear();
 
254
                b = tc.createTorrentFileStream(0,true,this);
 
255
                QVERIFY(b);
 
256
        }
 
257
        
 
258
private:
 
259
        DummyTorrentCreator creator;
 
260
        bt::TorrentControl tc;
 
261
};
 
262
 
 
263
QTEST_MAIN(TorrentFileStreamTest)
 
264
 
 
265
#include "torrentfilestreamtest.moc"
 
 
b'\\ No newline at end of file'