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 %07d\n"; 19 static const int VBL_LINE_LENGTH = 84; // Without the final '\n' ! 20 21 static const qint64 SL_NB_LINES = 5000LL; 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 // Register for notification file is loaded 37 connect( &logData, SIGNAL( loadingFinished( bool ) ), 38 this, SLOT( loadingFinished() ) ); 39 40 QBENCHMARK { 41 logData.attachFile( TMPDIR "/verybiglog.txt" ); 42 // Wait for the loading to be done 43 { 44 QApplication::exec(); 45 } 46 } 47 QCOMPARE( (qint64) progressSpy.count(), logData.getFileSize() / (5LL*1024*1024) + 2 ); 48 // Blocks of 5 MiB + 1 for the start notification (0%) 49 QCOMPARE( logData.getNbLine(), VBL_NB_LINES ); 50 QCOMPARE( logData.getMaxLength(), VBL_LINE_LENGTH ); 51 QCOMPARE( logData.getLineLength( 123 ), VBL_LINE_LENGTH ); 52 QCOMPARE( logData.getFileSize(), VBL_NB_LINES * (VBL_LINE_LENGTH+1LL) ); 53 54 // Disconnect all signals 55 disconnect( &logData, 0 ); 56 } 57 58 void TestLogData::multipleLoad() 59 { 60 LogData logData; 61 QSignalSpy finishedSpy( &logData, SIGNAL( loadingFinished( bool ) ) ); 62 63 // Register for notification file is loaded 64 connect( &logData, SIGNAL( loadingFinished( bool ) ), 65 this, SLOT( loadingFinished() ) ); 66 67 // Start loading the VBL 68 logData.attachFile( TMPDIR "/verybiglog.txt" ); 69 70 // Immediately interrupt the loading 71 logData.interruptLoading(); 72 73 // and wait for the signal 74 QApplication::exec(); 75 76 // Check we have an empty file 77 QCOMPARE( finishedSpy.count(), 1 ); 78 // TODO: check loadingFinished arg == false 79 QCOMPARE( logData.getNbLine(), 0LL ); 80 QCOMPARE( logData.getMaxLength(), 0 ); 81 QCOMPARE( logData.getFileSize(), 0LL ); 82 83 // Restart the VBL 84 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 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 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( bool ) ) ); 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( bool ) ), 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 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(), 200LL ); 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(), 400LL ); 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(), 0LL ); 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( bool ) ), 201 this, SLOT( loadingFinished() ) ); 202 203 logData.attachFile( TMPDIR "/verybiglog.txt" ); 204 205 // Wait for the loading to be done 206 { 207 QApplication::exec(); 208 } 209 210 // Read all lines sequentially 211 QString s; 212 QBENCHMARK { 213 for (int i = 0; i < VBL_NB_LINES; i++) { 214 s = logData.getLineString(i); 215 } 216 } 217 QCOMPARE( s.length(), VBL_LINE_LENGTH ); 218 } 219 220 void TestLogData::randomPageRead() 221 { 222 LogData logData; 223 224 // Register for notification file is loaded 225 connect( &logData, SIGNAL( loadingFinished( bool ) ), 226 this, SLOT( loadingFinished() ) ); 227 228 logData.attachFile( TMPDIR "/verybiglog.txt" ); 229 // Wait for the loading to be done 230 { 231 QApplication::exec(); 232 } 233 234 QWARN("Starting random page read test"); 235 236 // Read page by page from the beginning and the end, using the QStringList 237 // function 238 QStringList list; 239 QBENCHMARK { 240 for (int page = 0; page < (VBL_NB_LINES/VBL_LINE_PER_PAGE)-1; page++) 241 { 242 list = logData.getLines( page*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 243 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 244 int page_from_end = (VBL_NB_LINES/VBL_LINE_PER_PAGE) - page - 1; 245 list = logData.getLines( page_from_end*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 246 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 247 } 248 } 249 } 250 251 // 252 // Private functions 253 // 254 void TestLogData::loadingFinished() 255 { 256 QApplication::quit(); 257 } 258 259 bool TestLogData::generateDataFiles() 260 { 261 char newLine[90]; 262 263 QFile file( TMPDIR "/verybiglog.txt" ); 264 if ( file.open( QIODevice::WriteOnly ) ) { 265 for (int i = 0; i < VBL_NB_LINES; i++) { 266 snprintf(newLine, 89, vbl_format, i); 267 file.write( newLine, qstrlen(newLine) ); 268 } 269 } 270 else { 271 return false; 272 } 273 file.close(); 274 275 file.setFileName( TMPDIR "/smalllog.txt" ); 276 if ( file.open( QIODevice::WriteOnly ) ) { 277 for (int i = 0; i < SL_NB_LINES; i++) { 278 snprintf(newLine, 89, sl_format, i); 279 file.write( newLine, qstrlen(newLine) ); 280 } 281 } 282 else { 283 return false; 284 } 285 file.close(); 286 287 return true; 288 } 289