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