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\t\t%07d\n"; 19 static const int VBL_LINE_LENGTH = (76+2+7) ; // Without the final '\n' ! 20 static const int VBL_VISIBLE_LINE_LENGTH = (76+8+4+7); // Without the final '\n' ! 21 22 static const qint64 SL_NB_LINES = 5000LL; 23 static const int SL_LINE_PER_PAGE = 70; 24 static const char* sl_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line %06d\n"; 25 static const int SL_LINE_LENGTH = 83; // Without the final '\n' ! 26 27 void TestLogData::initTestCase() 28 { 29 QVERIFY( generateDataFiles() ); 30 } 31 32 void TestLogData::simpleLoad() 33 { 34 LogData logData; 35 QSignalSpy progressSpy( &logData, SIGNAL( loadingProgressed( int ) ) ); 36 37 // Register for notification file is loaded 38 connect( &logData, SIGNAL( loadingFinished( bool ) ), 39 this, SLOT( loadingFinished() ) ); 40 41 QBENCHMARK { 42 logData.attachFile( TMPDIR "/verybiglog.txt" ); 43 // Wait for the loading to be done 44 { 45 QApplication::exec(); 46 } 47 } 48 QCOMPARE( (qint64) progressSpy.count(), logData.getFileSize() / (5LL*1024*1024) + 2 ); 49 // Blocks of 5 MiB + 1 for the start notification (0%) 50 QCOMPARE( logData.getNbLine(), VBL_NB_LINES ); 51 QCOMPARE( logData.getMaxLength(), VBL_VISIBLE_LINE_LENGTH ); 52 QCOMPARE( logData.getLineLength( 123 ), VBL_VISIBLE_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( bool ) ) ); 63 64 // Register for notification file is loaded 65 connect( &logData, SIGNAL( loadingFinished( bool ) ), 66 this, SLOT( loadingFinished() ) ); 67 68 // Start loading the VBL 69 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 // TODO: check loadingFinished arg == false 80 QCOMPARE( logData.getNbLine(), 0LL ); 81 QCOMPARE( logData.getMaxLength(), 0 ); 82 QCOMPARE( logData.getFileSize(), 0LL ); 83 84 // Restart the VBL 85 logData.attachFile( TMPDIR "/verybiglog.txt" ); 86 87 // Ensure the counting has started 88 { 89 QMutex mutex; 90 QWaitCondition sleep; 91 // sleep.wait( &mutex, 10 ); 92 } 93 94 // Load the SL (should block until VBL is fully indexed) 95 logData.attachFile( TMPDIR "/smalllog.txt" ); 96 97 // and wait for the 2 signals (one for each file) 98 QApplication::exec(); 99 QApplication::exec(); 100 101 // Check we have the small log loaded 102 QCOMPARE( finishedSpy.count(), 3 ); 103 QCOMPARE( logData.getNbLine(), SL_NB_LINES ); 104 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 105 QCOMPARE( logData.getFileSize(), SL_NB_LINES * (SL_LINE_LENGTH+1LL) ); 106 107 // Restart the VBL again 108 logData.attachFile( TMPDIR "/verybiglog.txt" ); 109 110 // Immediately interrupt the loading 111 logData.interruptLoading(); 112 113 // and wait for the signal 114 QApplication::exec(); 115 116 // Check the small log has been restored 117 QCOMPARE( finishedSpy.count(), 4 ); 118 QCOMPARE( logData.getNbLine(), SL_NB_LINES ); 119 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 120 QCOMPARE( logData.getFileSize(), SL_NB_LINES * (SL_LINE_LENGTH+1LL) ); 121 122 // Disconnect all signals 123 disconnect( &logData, 0 ); 124 } 125 126 void TestLogData::changingFile() 127 { 128 char newLine[90]; 129 LogData logData; 130 131 QSignalSpy finishedSpy( &logData, SIGNAL( loadingFinished( bool ) ) ); 132 QSignalSpy progressSpy( &logData, SIGNAL( loadingProgressed( int ) ) ); 133 QSignalSpy changedSpy( &logData, 134 SIGNAL( fileChanged( LogData::MonitoredFileStatus ) ) ); 135 136 // Register for notification file is loaded 137 connect( &logData, SIGNAL( loadingFinished( bool ) ), 138 this, SLOT( loadingFinished() ) ); 139 140 // Generate a small file 141 QFile file( TMPDIR "/changingfile.txt" ); 142 if ( file.open( QIODevice::WriteOnly ) ) { 143 for (int i = 0; i < 200; i++) { 144 snprintf(newLine, 89, sl_format, i); 145 file.write( newLine, qstrlen(newLine) ); 146 } 147 } 148 file.close(); 149 150 // Start loading it 151 logData.attachFile( TMPDIR "/changingfile.txt" ); 152 153 // and wait for the signal 154 QApplication::exec(); 155 156 // Check we have the small file 157 QCOMPARE( finishedSpy.count(), 1 ); 158 QCOMPARE( logData.getNbLine(), 200LL ); 159 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 160 QCOMPARE( logData.getFileSize(), 200 * (SL_LINE_LENGTH+1LL) ); 161 162 // Add some data to it 163 if ( file.open( QIODevice::Append ) ) { 164 for (int i = 0; i < 200; i++) { 165 snprintf(newLine, 89, sl_format, i); 166 file.write( newLine, qstrlen(newLine) ); 167 } 168 } 169 file.close(); 170 171 // and wait for the signals 172 QApplication::exec(); 173 174 // Check we have a bigger file 175 QCOMPARE( changedSpy.count(), 1 ); 176 QCOMPARE( finishedSpy.count(), 2 ); 177 QCOMPARE( logData.getNbLine(), 400LL ); 178 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 179 QCOMPARE( logData.getFileSize(), 400 * (SL_LINE_LENGTH+1LL) ); 180 181 // Truncate the file 182 QVERIFY( file.open( QIODevice::WriteOnly ) ); 183 file.close(); 184 185 // and wait for the signals 186 QApplication::exec(); 187 188 // Check we have an empty file 189 QCOMPARE( changedSpy.count(), 2 ); 190 QCOMPARE( finishedSpy.count(), 3 ); 191 QCOMPARE( logData.getNbLine(), 0LL ); 192 QCOMPARE( logData.getMaxLength(), 0 ); 193 QCOMPARE( logData.getFileSize(), 0LL ); 194 } 195 196 void TestLogData::sequentialRead() 197 { 198 LogData logData; 199 200 // Register for notification file is loaded 201 connect( &logData, SIGNAL( loadingFinished( bool ) ), 202 this, SLOT( loadingFinished() ) ); 203 204 logData.attachFile( TMPDIR "/verybiglog.txt" ); 205 206 // Wait for the loading to be done 207 { 208 QApplication::exec(); 209 } 210 211 // Read all lines sequentially 212 QString s; 213 QBENCHMARK { 214 for (int i = 0; i < VBL_NB_LINES; i++) { 215 s = logData.getLineString(i); 216 } 217 } 218 QCOMPARE( s.length(), VBL_LINE_LENGTH ); 219 220 } 221 222 void TestLogData::sequentialReadExpanded() 223 { 224 LogData logData; 225 226 // Register for notification file is loaded 227 connect( &logData, SIGNAL( loadingFinished( bool ) ), 228 this, SLOT( loadingFinished() ) ); 229 230 logData.attachFile( TMPDIR "/verybiglog.txt" ); 231 232 // Wait for the loading to be done 233 { 234 QApplication::exec(); 235 } 236 237 // Read all expanded lines sequentially 238 QString s; 239 QBENCHMARK { 240 for (int i = 0; i < VBL_NB_LINES; i++) { 241 s = logData.getExpandedLineString(i); 242 } 243 } 244 QCOMPARE( s.length(), VBL_VISIBLE_LINE_LENGTH ); 245 } 246 247 void TestLogData::randomPageRead() 248 { 249 LogData logData; 250 251 // Register for notification file is loaded 252 connect( &logData, SIGNAL( loadingFinished( bool ) ), 253 this, SLOT( loadingFinished() ) ); 254 255 logData.attachFile( TMPDIR "/verybiglog.txt" ); 256 // Wait for the loading to be done 257 { 258 QApplication::exec(); 259 } 260 261 QWARN("Starting random page read test"); 262 263 // Read page by page from the beginning and the end, using the QStringList 264 // function 265 QStringList list; 266 QBENCHMARK { 267 for (int page = 0; page < (VBL_NB_LINES/VBL_LINE_PER_PAGE)-1; page++) 268 { 269 list = logData.getLines( page*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 270 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 271 int page_from_end = (VBL_NB_LINES/VBL_LINE_PER_PAGE) - page - 1; 272 list = logData.getLines( page_from_end*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 273 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 274 } 275 } 276 277 } 278 279 void TestLogData::randomPageReadExpanded() 280 { 281 LogData logData; 282 283 // Register for notification file is loaded 284 connect( &logData, SIGNAL( loadingFinished( bool ) ), 285 this, SLOT( loadingFinished() ) ); 286 287 logData.attachFile( TMPDIR "/verybiglog.txt" ); 288 // Wait for the loading to be done 289 { 290 QApplication::exec(); 291 } 292 293 QWARN("Starting random page read test (expanded lines)"); 294 295 // Read page by page from the beginning and the end, using the QStringList 296 // function 297 QStringList list; 298 QBENCHMARK { 299 for (int page = 0; page < (VBL_NB_LINES/VBL_LINE_PER_PAGE)-1; page++) 300 { 301 list = logData.getExpandedLines( page*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 302 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 303 int page_from_end = (VBL_NB_LINES/VBL_LINE_PER_PAGE) - page - 1; 304 list = logData.getExpandedLines( page_from_end*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 305 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 306 } 307 } 308 } 309 310 // 311 // Private functions 312 // 313 void TestLogData::loadingFinished() 314 { 315 QApplication::quit(); 316 } 317 318 bool TestLogData::generateDataFiles() 319 { 320 char newLine[90]; 321 322 QFile file( TMPDIR "/verybiglog.txt" ); 323 if ( file.open( QIODevice::WriteOnly ) ) { 324 for (int i = 0; i < VBL_NB_LINES; i++) { 325 snprintf(newLine, 89, vbl_format, i); 326 file.write( newLine, qstrlen(newLine) ); 327 } 328 } 329 else { 330 return false; 331 } 332 file.close(); 333 334 file.setFileName( TMPDIR "/smalllog.txt" ); 335 if ( file.open( QIODevice::WriteOnly ) ) { 336 for (int i = 0; i < SL_NB_LINES; i++) { 337 snprintf(newLine, 89, sl_format, i); 338 file.write( newLine, qstrlen(newLine) ); 339 } 340 } 341 else { 342 return false; 343 } 344 file.close(); 345 346 return true; 347 } 348