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