xref: /glogg/tests/testlogdata.cpp (revision 5fc7617d4670de0ceec483782054b84b635c0a93)
1 #include <QSignalSpy>
2 #include <QMutexLocker>
3 #include <QFile>
4 
5 #include "testlogdata.h"
6 #include "logdata.h"
7 
8 #if QT_VERSION < 0x040500
9 #define QBENCHMARK
10 #endif
11 
12 #if !defined( TMPDIR )
13 #define TMPDIR "/tmp"
14 #endif
15 
16 static const qint64 VBL_NB_LINES = 4999999LL;
17 static const int VBL_LINE_PER_PAGE = 70;
18 static const char* vbl_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line\t\t%07d\n";
19 static const int VBL_LINE_LENGTH = (76+2+7) ; // Without the final '\n' !
20 static const int VBL_VISIBLE_LINE_LENGTH = (76+8+4+7); // Without the final '\n' !
21 
22 static const qint64 SL_NB_LINES = 5000LL;
23 static const int SL_LINE_PER_PAGE = 70;
24 static const char* sl_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line %06d\n";
25 static const int SL_LINE_LENGTH = 83; // Without the final '\n' !
26 
27 void TestLogData::initTestCase()
28 {
29     QVERIFY( generateDataFiles() );
30 }
31 
32 void TestLogData::simpleLoad()
33 {
34     LogData logData;
35     QSignalSpy progressSpy( &logData, SIGNAL( loadingProgressed( int ) ) );
36 
37     // Register for notification file is loaded
38     connect( &logData, SIGNAL( loadingFinished( bool ) ),
39             this, SLOT( loadingFinished() ) );
40 
41     QBENCHMARK {
42         logData.attachFile( TMPDIR "/verybiglog.txt" );
43         // Wait for the loading to be done
44         {
45             QApplication::exec();
46         }
47     }
48     QCOMPARE( (qint64) progressSpy.count(), logData.getFileSize() / (5LL*1024*1024) + 2 );
49     // Blocks of 5 MiB + 1 for the start notification (0%)
50     QCOMPARE( logData.getNbLine(), VBL_NB_LINES );
51     QCOMPARE( logData.getMaxLength(), VBL_VISIBLE_LINE_LENGTH );
52     QCOMPARE( logData.getLineLength( 123 ), VBL_VISIBLE_LINE_LENGTH );
53     QCOMPARE( logData.getFileSize(), VBL_NB_LINES * (VBL_LINE_LENGTH+1LL) );
54 
55     // Disconnect all signals
56     disconnect( &logData, 0 );
57 }
58 
59 void TestLogData::multipleLoad()
60 {
61     LogData logData;
62     QSignalSpy finishedSpy( &logData, SIGNAL( loadingFinished( bool ) ) );
63 
64     // Register for notification file is loaded
65     connect( &logData, SIGNAL( loadingFinished( bool ) ),
66             this, SLOT( loadingFinished() ) );
67 
68     // Start loading the VBL
69     logData.attachFile( TMPDIR "/verybiglog.txt" );
70 
71     // Immediately interrupt the loading
72     logData.interruptLoading();
73 
74     // and wait for the signal
75     QApplication::exec();
76 
77     // Check we have an empty file
78     QCOMPARE( finishedSpy.count(), 1 );
79     // TODO: check loadingFinished arg == false
80     QCOMPARE( logData.getNbLine(), 0LL );
81     QCOMPARE( logData.getMaxLength(), 0 );
82     QCOMPARE( logData.getFileSize(), 0LL );
83 
84     // Restart the VBL
85     logData.attachFile( TMPDIR "/verybiglog.txt" );
86 
87     // Ensure the counting has started
88     {
89         QMutex mutex;
90         QWaitCondition sleep;
91         // sleep.wait( &mutex, 10 );
92     }
93 
94     // Load the SL (should block until VBL is fully indexed)
95     logData.attachFile( TMPDIR "/smalllog.txt" );
96 
97     // and wait for the 2 signals (one for each file)
98     QApplication::exec();
99     QApplication::exec();
100 
101     // Check we have the small log loaded
102     QCOMPARE( finishedSpy.count(), 3 );
103     QCOMPARE( logData.getNbLine(), SL_NB_LINES );
104     QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH );
105     QCOMPARE( logData.getFileSize(), SL_NB_LINES * (SL_LINE_LENGTH+1LL) );
106 
107     // Restart the VBL again
108     logData.attachFile( TMPDIR "/verybiglog.txt" );
109 
110     // Immediately interrupt the loading
111     logData.interruptLoading();
112 
113     // and wait for the signal
114     QApplication::exec();
115 
116     // Check the small log has been restored
117     QCOMPARE( finishedSpy.count(), 4 );
118     QCOMPARE( logData.getNbLine(), SL_NB_LINES );
119     QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH );
120     QCOMPARE( logData.getFileSize(), SL_NB_LINES * (SL_LINE_LENGTH+1LL) );
121 
122     // Disconnect all signals
123     disconnect( &logData, 0 );
124 }
125 
126 void TestLogData::changingFile()
127 {
128     char newLine[90];
129     LogData logData;
130 
131     QSignalSpy finishedSpy( &logData, SIGNAL( loadingFinished( bool ) ) );
132     QSignalSpy progressSpy( &logData, SIGNAL( loadingProgressed( int ) ) );
133     QSignalSpy changedSpy( &logData,
134             SIGNAL( fileChanged( LogData::MonitoredFileStatus ) ) );
135 
136     // Register for notification file is loaded
137     connect( &logData, SIGNAL( loadingFinished( bool ) ),
138             this, SLOT( loadingFinished() ) );
139 
140     // Generate a small file
141     QFile file( TMPDIR "/changingfile.txt" );
142     if ( file.open( QIODevice::WriteOnly ) ) {
143         for (int i = 0; i < 200; i++) {
144             snprintf(newLine, 89, sl_format, i);
145             file.write( newLine, qstrlen(newLine) );
146         }
147     }
148     file.close();
149 
150     // Start loading it
151     logData.attachFile( TMPDIR "/changingfile.txt" );
152 
153     // and wait for the signal
154     QApplication::exec();
155 
156     // Check we have the small file
157     QCOMPARE( finishedSpy.count(), 1 );
158     QCOMPARE( logData.getNbLine(), 200LL );
159     QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH );
160     QCOMPARE( logData.getFileSize(), 200 * (SL_LINE_LENGTH+1LL) );
161 
162     // Add some data to it
163     if ( file.open( QIODevice::Append ) ) {
164         for (int i = 0; i < 200; i++) {
165             snprintf(newLine, 89, sl_format, i);
166             file.write( newLine, qstrlen(newLine) );
167         }
168     }
169     file.close();
170 
171     // and wait for the signals
172     QApplication::exec();
173 
174     // Check we have a bigger file
175     QCOMPARE( changedSpy.count(), 1 );
176     QCOMPARE( finishedSpy.count(), 2 );
177     QCOMPARE( logData.getNbLine(), 400LL );
178     QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH );
179     QCOMPARE( logData.getFileSize(), 400 * (SL_LINE_LENGTH+1LL) );
180 
181     // Truncate the file
182     QVERIFY( file.open( QIODevice::WriteOnly ) );
183     file.close();
184 
185     // and wait for the signals
186     QApplication::exec();
187 
188     // Check we have an empty file
189     QCOMPARE( changedSpy.count(), 2 );
190     QCOMPARE( finishedSpy.count(), 3 );
191     QCOMPARE( logData.getNbLine(), 0LL );
192     QCOMPARE( logData.getMaxLength(), 0 );
193     QCOMPARE( logData.getFileSize(), 0LL );
194 }
195 
196 void TestLogData::sequentialRead()
197 {
198     LogData logData;
199 
200     // Register for notification file is loaded
201     connect( &logData, SIGNAL( loadingFinished( bool ) ),
202             this, SLOT( loadingFinished() ) );
203 
204     logData.attachFile( TMPDIR "/verybiglog.txt" );
205 
206     // Wait for the loading to be done
207     {
208         QApplication::exec();
209     }
210 
211     // Read all lines sequentially
212     QString s;
213     QBENCHMARK {
214         for (int i = 0; i < VBL_NB_LINES; i++) {
215             s = logData.getLineString(i);
216         }
217     }
218     QCOMPARE( s.length(), VBL_LINE_LENGTH );
219 
220 }
221 
222 void TestLogData::sequentialReadExpanded()
223 {
224     LogData logData;
225 
226     // Register for notification file is loaded
227     connect( &logData, SIGNAL( loadingFinished( bool ) ),
228             this, SLOT( loadingFinished() ) );
229 
230     logData.attachFile( TMPDIR "/verybiglog.txt" );
231 
232     // Wait for the loading to be done
233     {
234         QApplication::exec();
235     }
236 
237     // Read all expanded lines sequentially
238     QString s;
239     QBENCHMARK {
240         for (int i = 0; i < VBL_NB_LINES; i++) {
241             s = logData.getExpandedLineString(i);
242         }
243     }
244     QCOMPARE( s.length(), VBL_VISIBLE_LINE_LENGTH );
245 }
246 
247 void TestLogData::randomPageRead()
248 {
249     LogData logData;
250 
251     // Register for notification file is loaded
252     connect( &logData, SIGNAL( loadingFinished( bool ) ),
253             this, SLOT( loadingFinished() ) );
254 
255     logData.attachFile( TMPDIR "/verybiglog.txt" );
256     // Wait for the loading to be done
257     {
258         QApplication::exec();
259     }
260 
261     QWARN("Starting random page read test");
262 
263     // Read page by page from the beginning and the end, using the QStringList
264     // function
265     QStringList list;
266     QBENCHMARK {
267         for (int page = 0; page < (VBL_NB_LINES/VBL_LINE_PER_PAGE)-1; page++)
268         {
269             list = logData.getLines( page*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE );
270             QCOMPARE(list.count(), VBL_LINE_PER_PAGE);
271             int page_from_end = (VBL_NB_LINES/VBL_LINE_PER_PAGE) - page - 1;
272             list = logData.getLines( page_from_end*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE );
273             QCOMPARE(list.count(), VBL_LINE_PER_PAGE);
274         }
275     }
276 
277 }
278 
279 void TestLogData::randomPageReadExpanded()
280 {
281     LogData logData;
282 
283     // Register for notification file is loaded
284     connect( &logData, SIGNAL( loadingFinished( bool ) ),
285             this, SLOT( loadingFinished() ) );
286 
287     logData.attachFile( TMPDIR "/verybiglog.txt" );
288     // Wait for the loading to be done
289     {
290         QApplication::exec();
291     }
292 
293     QWARN("Starting random page read test (expanded lines)");
294 
295     // Read page by page from the beginning and the end, using the QStringList
296     // function
297     QStringList list;
298     QBENCHMARK {
299         for (int page = 0; page < (VBL_NB_LINES/VBL_LINE_PER_PAGE)-1; page++)
300         {
301             list = logData.getExpandedLines( page*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE );
302             QCOMPARE(list.count(), VBL_LINE_PER_PAGE);
303             int page_from_end = (VBL_NB_LINES/VBL_LINE_PER_PAGE) - page - 1;
304             list = logData.getExpandedLines( page_from_end*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE );
305             QCOMPARE(list.count(), VBL_LINE_PER_PAGE);
306         }
307     }
308 }
309 
310 //
311 // Private functions
312 //
313 void TestLogData::loadingFinished()
314 {
315     QApplication::quit();
316 }
317 
318 bool TestLogData::generateDataFiles()
319 {
320     char newLine[90];
321 
322     QFile file( TMPDIR "/verybiglog.txt" );
323     if ( file.open( QIODevice::WriteOnly ) ) {
324         for (int i = 0; i < VBL_NB_LINES; i++) {
325             snprintf(newLine, 89, vbl_format, i);
326             file.write( newLine, qstrlen(newLine) );
327         }
328     }
329     else {
330         return false;
331     }
332     file.close();
333 
334     file.setFileName( TMPDIR "/smalllog.txt" );
335     if ( file.open( QIODevice::WriteOnly ) ) {
336         for (int i = 0; i < SL_NB_LINES; i++) {
337             snprintf(newLine, 89, sl_format, i);
338             file.write( newLine, qstrlen(newLine) );
339         }
340     }
341     else {
342         return false;
343     }
344     file.close();
345 
346     return true;
347 }
348