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 // Performs two searches in a row 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 } 198 file.close(); 199 200 // Start an update search 201 filteredData->updateSearch(); 202 203 for ( int i = 0; i < 3; i++ ) 204 QApplication::exec(); 205 206 // Check the result 207 QCOMPARE( filteredData->getNbLine(), 25LL ); 208 QCOMPARE( progressSpy.count(), 4 ); 209 } 210 211 // 212 // Private functions 213 // 214 void TestLogFilteredData::loadingFinished() 215 { 216 QApplication::quit(); 217 } 218 219 void TestLogFilteredData::searchProgressed( int nbMatches, int completion ) 220 { 221 QApplication::quit(); 222 } 223 224 bool TestLogFilteredData::generateDataFiles() 225 { 226 char newLine[90]; 227 228 QFile file( TMPDIR "/mediumlog.txt" ); 229 if ( file.open( QIODevice::WriteOnly ) ) { 230 for (int i = 0; i < ML_NB_LINES; i++) { 231 snprintf(newLine, 89, ml_format, i); 232 file.write( newLine, qstrlen(newLine) ); 233 } 234 } 235 else { 236 return false; 237 } 238 file.close(); 239 240 file.setFileName( TMPDIR "/smalllog.txt" ); 241 if ( file.open( QIODevice::WriteOnly ) ) { 242 for (int i = 0; i < SL_NB_LINES; i++) { 243 snprintf(newLine, 89, sl_format, i); 244 file.write( newLine, qstrlen(newLine) ); 245 } 246 } 247 else { 248 return false; 249 } 250 file.close(); 251 252 return true; 253 } 254