xref: /glogg/tests/testlogdata.cpp (revision 3cf2e1a18bebfa15d75f383544af5b63f577c9ea)
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 int VBL_NB_LINES = 4999999;
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 int SL_NB_LINES = 5000;
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     // First try to log a non existent file
37     QVERIFY( logData.attachFile( "/non/existent/file" ) == false );
38 
39     // Register for notification file is loaded
40     connect( &logData, SIGNAL( loadingFinished() ),
41             this, SLOT( loadingFinished() ) );
42 
43     QBENCHMARK {
44         QVERIFY( logData.attachFile( TMPDIR "/verybiglog.txt" ) );
45         // Wait for the loading to be done
46         {
47             QApplication::exec();
48         }
49     }
50     QCOMPARE( (qint64) progressSpy.count(), logData.getFileSize() / (5LL*1024*1024) + 1 );
51     QCOMPARE( logData.getNbLine(), VBL_NB_LINES );
52     QCOMPARE( logData.getMaxLength(), VBL_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() ) );
63 
64     // Register for notification file is loaded
65     connect( &logData, SIGNAL( loadingFinished() ),
66             this, SLOT( loadingFinished() ) );
67 
68     // Start loading the VBL
69     QVERIFY( 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     QCOMPARE( logData.getNbLine(), 0 );
80     QCOMPARE( logData.getMaxLength(), 0 );
81     QCOMPARE( logData.getFileSize(), 0LL );
82 
83     // Restart the VBL
84     QVERIFY( 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     QVERIFY( 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     QVERIFY( 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() ) );
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() ),
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     QVERIFY( 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(), 200 );
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(), 400 );
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(), 0 );
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() ),
201             this, SLOT( loadingFinished() ) );
202 
203     logData.attachFile( TMPDIR "/verybiglog.txt" );
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 #if 0
220 void TestLogData::randomPageRead()
221 {
222     LogData* logData;
223 
224     {
225         QByteArray array = generateData();
226         logData = new LogData(array);
227     }
228 
229     // Read page by page from the beginning and the end
230     QString s;
231     QBENCHMARK {
232         for (int page = 0; page < (NB_LINES/LINE_PER_PAGE)-1; page++)
233         {
234             for (int i = page*LINE_PER_PAGE; i < ((page+1)*LINE_PER_PAGE); i++)
235                 s = logData->getLineString(i);
236             int page_from_end = (NB_LINES/LINE_PER_PAGE) - page - 1;
237             for (int i = page_from_end*LINE_PER_PAGE; i < ((page_from_end+1)*LINE_PER_PAGE); i++)
238                 s = logData->getLineString(i);
239         }
240     }
241     QVERIFY(s.length() > 0);
242 
243     delete logData;
244 }
245 #endif
246 
247 //
248 // Private functions
249 //
250 void TestLogData::loadingFinished()
251 {
252     QApplication::quit();
253 }
254 
255 bool TestLogData::generateDataFiles()
256 {
257     char newLine[90];
258 
259     QFile file( TMPDIR "/verybiglog.txt" );
260     if ( file.open( QIODevice::WriteOnly ) ) {
261         for (int i = 0; i < VBL_NB_LINES; i++) {
262             snprintf(newLine, 89, vbl_format, i);
263             file.write( newLine, qstrlen(newLine) );
264         }
265     }
266     else {
267         return false;
268     }
269     file.close();
270 
271     file.setFileName( TMPDIR "/smalllog.txt" );
272     if ( file.open( QIODevice::WriteOnly ) ) {
273         for (int i = 0; i < SL_NB_LINES; i++) {
274             snprintf(newLine, 89, sl_format, i);
275             file.write( newLine, qstrlen(newLine) );
276         }
277     }
278     else {
279         return false;
280     }
281     file.close();
282 
283     return true;
284 }
285