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