xref: /glogg/tests/testlogfiltereddata.cpp (revision 5db60fd3a2c5a247bcf306900766bf2bc7ee28ea)
1 #include <QSignalSpy>
2 #include <QMutexLocker>
3 #include <QFile>
4 
5 #include "testlogfiltereddata.h"
6 #include "logdata.h"
7 #include "logfiltereddata.h"
8 
9 #if QT_VERSION < 0x040500
10 #define QBENCHMARK
11 #endif
12 
13 #if !defined( TMPDIR )
14 #define TMPDIR "/tmp"
15 #endif
16 
17 static const qint64 ML_NB_LINES = 15000LL;
18 static const char* ml_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line\t\t%06d\n";
19 static const int ML_VISIBLE_LINE_LENGTH = (76+8+4+6); // Without the final '\n' !
20 
21 static const qint64 SL_NB_LINES = 2000LL;
22 static const char* sl_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line %06d\n";
23 
24 void TestLogFilteredData::initTestCase()
25 {
26     QVERIFY( generateDataFiles() );
27 }
28 
29 void TestLogFilteredData::simpleSearch()
30 {
31     LogData logData;
32 
33     // First load the tests file
34     // Register for notification file is loaded
35     connect( &logData, SIGNAL( loadingFinished( bool ) ),
36             this, SLOT( loadingFinished() ) );
37 
38     logData.attachFile( TMPDIR "/mediumlog.txt" );
39     // Wait for the loading to be done
40     {
41         QApplication::exec();
42     }
43 
44     QCOMPARE( logData.getNbLine(), ML_NB_LINES );
45 
46     // Now perform a simple search
47     LogFilteredData* filteredData = logData.getNewFilteredData();
48     connect( filteredData, SIGNAL( searchProgressed( int, int ) ),
49             this, SLOT( searchProgressed( int, int ) ) );
50 
51     QSignalSpy progressSpy( filteredData, SIGNAL( searchProgressed( int, int ) ) );
52 
53     qint64 matches[] = { 0, 15, 20, 135 };
54     QBENCHMARK {
55         // Start the search
56         filteredData->runSearch( QRegExp( "123" ) );
57 
58         // And check we receive data in 4 chunks (the first being empty)
59         for ( int i = 0; i < 4; i++ ) {
60             QApplication::exec();
61             QCOMPARE( filteredData->getNbLine(), matches[i] );
62         }
63     }
64 
65     QCOMPARE( progressSpy.count(), 4 );
66 
67     // Check the search
68     QCOMPARE( filteredData->isLineInMatchingList( 123 ), true );
69     QCOMPARE( filteredData->isLineInMatchingList( 124 ), false );
70     QCOMPARE( filteredData->getMaxLength(), ML_VISIBLE_LINE_LENGTH );
71     QCOMPARE( filteredData->getLineLength( 12 ), ML_VISIBLE_LINE_LENGTH );
72     QCOMPARE( filteredData->getNbLine(), 135LL );
73     // Line beyond limit
74     QCOMPARE( filteredData->isLineInMatchingList( 60000 ), false );
75     QCOMPARE( filteredData->getMatchingLineNumber( 0 ), 123LL );
76 
77     // Now let's try interrupting a search
78     filteredData->runSearch( QRegExp( "123" ) );
79     // ... wait for two chunks.
80     QApplication::exec();
81     QApplication::exec();
82     // and interrupt!
83     filteredData->interruptSearch();
84     QCOMPARE( filteredData->getNbLine(), matches[1] );
85     QApplication::exec();
86     // After interrupt: should be 100% and the same number of matches
87     QCOMPARE( filteredData->getNbLine(), matches[2] );
88 
89     // (because there is no guarantee when the search is
90     // interrupted, we are not sure how many chunk of result
91     // we will get.)
92 
93     // Disconnect all signals
94     disconnect( &logData, 0 );
95 
96     // Destroy the filtered data
97     delete filteredData;
98 }
99 
100 void TestLogFilteredData::multipleSearch()
101 {
102     LogData logData;
103 
104     // First load the tests file
105     // Register for notification file is loaded
106     connect( &logData, SIGNAL( loadingFinished( bool ) ),
107             this, SLOT( loadingFinished() ) );
108 
109     logData.attachFile( TMPDIR "/smalllog.txt" );
110     // Wait for the loading to be done
111     {
112         QApplication::exec();
113     }
114 
115     QCOMPARE( logData.getNbLine(), SL_NB_LINES );
116 
117     // Performs two searches in a row
118     LogFilteredData* filteredData = logData.getNewFilteredData();
119     connect( filteredData, SIGNAL( searchProgressed( int, int ) ),
120             this, SLOT( searchProgressed( int, int ) ) );
121 
122     QSignalSpy progressSpy( filteredData,
123             SIGNAL( searchProgressed( int, int ) ) );
124 
125     // Start the search, and immediately another one
126     // (the second call should block until the first search is done)
127     filteredData->runSearch( QRegExp( "1234" ) );
128     filteredData->runSearch( QRegExp( "123" ) );
129 
130     for ( int i = 0; i < 3; i++ )
131         QApplication::exec();
132 
133     // We should have the result for the 2nd search
134     QCOMPARE( filteredData->getNbLine(), 12LL );
135 
136     QCOMPARE( progressSpy.count(), 4 );
137 
138     // Now a tricky one: we run a search and immediately attach a new file
139     filteredData->runSearch( QRegExp( "123" ) );
140     QApplication::exec();
141     logData.attachFile( TMPDIR "/mediumlog.txt" );
142 
143     // We don't expect meaningful results but it should not crash!
144     for ( int i = 0; i < 2; i++ )
145         QApplication::exec();
146 
147     // Disconnect all signals
148     disconnect( &logData, 0 );
149 
150     // Destroy the filtered data
151     delete filteredData;
152 }
153 
154 void TestLogFilteredData::updateSearch()
155 {
156     LogData logData;
157 
158     // First load the tests file
159     // Register for notification file is loaded
160     connect( &logData, SIGNAL( loadingFinished( bool ) ),
161             this, SLOT( loadingFinished() ) );
162 
163     logData.attachFile( TMPDIR "/smalllog.txt" );
164     // Wait for the loading to be done
165     {
166         QApplication::exec();
167     }
168 
169     QCOMPARE( logData.getNbLine(), SL_NB_LINES );
170 
171     // Perform a first search
172     LogFilteredData* filteredData = logData.getNewFilteredData();
173     connect( filteredData, SIGNAL( searchProgressed( int, int ) ),
174             this, SLOT( searchProgressed( int, int ) ) );
175 
176     QSignalSpy progressSpy( filteredData,
177             SIGNAL( searchProgressed( int, int ) ) );
178 
179     // Start a search
180     filteredData->runSearch( QRegExp( "123" ) );
181 
182     for ( int i = 0; i < 2; i++ )
183         QApplication::exec();
184 
185     // Check the result
186     QCOMPARE( filteredData->getNbLine(), 12LL );
187     QCOMPARE( progressSpy.count(), 2 );
188 
189     // Add some data to the file
190     char newLine[90];
191     QFile file( TMPDIR "/smalllog.txt" );
192     if ( file.open( QIODevice::Append ) ) {
193         for (int i = 0; i < 3000; i++) {
194             snprintf(newLine, 89, sl_format, i);
195             file.write( newLine, qstrlen(newLine) );
196         }
197         // To test the edge case when the final line is not complete
198         snprintf(newLine, 89, "123... beginning of line.");
199         file.write( newLine, qstrlen(newLine) );
200     }
201     file.close();
202 
203     // Let the system do the update
204     QApplication::exec();
205 
206     // Start an update search
207     filteredData->updateSearch();
208 
209     for ( int i = 0; i < 2; i++ )
210         QApplication::exec();
211 
212     // Check the result
213     QCOMPARE( logData.getNbLine(), 5001LL );
214     QCOMPARE( filteredData->getNbLine(), 26LL );
215     QCOMPARE( progressSpy.count(), 4 );
216 }
217 
218 //
219 // Private functions
220 //
221 void TestLogFilteredData::loadingFinished()
222 {
223     QApplication::quit();
224 }
225 
226 void TestLogFilteredData::searchProgressed( int nbMatches, int completion )
227 {
228     QApplication::quit();
229 }
230 
231 bool TestLogFilteredData::generateDataFiles()
232 {
233     char newLine[90];
234 
235     QFile file( TMPDIR "/mediumlog.txt" );
236     if ( file.open( QIODevice::WriteOnly ) ) {
237         for (int i = 0; i < ML_NB_LINES; i++) {
238             snprintf(newLine, 89, ml_format, i);
239             file.write( newLine, qstrlen(newLine) );
240         }
241     }
242     else {
243         return false;
244     }
245     file.close();
246 
247     file.setFileName( TMPDIR "/smalllog.txt" );
248     if ( file.open( QIODevice::WriteOnly ) ) {
249         for (int i = 0; i < SL_NB_LINES; i++) {
250             snprintf(newLine, 89, sl_format, i);
251             file.write( newLine, qstrlen(newLine) );
252         }
253     }
254     else {
255         return false;
256     }
257     file.close();
258 
259     return true;
260 }
261