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) + 1 ); 48 QCOMPARE( logData.getNbLine(), VBL_NB_LINES ); 49 QCOMPARE( logData.getMaxLength(), VBL_LINE_LENGTH ); 50 QCOMPARE( logData.getFileSize(), VBL_NB_LINES * (VBL_LINE_LENGTH+1LL) ); 51 52 // Disconnect all signals 53 disconnect( &logData, 0 ); 54 } 55 56 void TestLogData::multipleLoad() 57 { 58 LogData logData; 59 QSignalSpy finishedSpy( &logData, SIGNAL( loadingFinished( bool ) ) ); 60 61 // Register for notification file is loaded 62 connect( &logData, SIGNAL( loadingFinished( bool ) ), 63 this, SLOT( loadingFinished() ) ); 64 65 // Start loading the VBL 66 logData.attachFile( TMPDIR "/verybiglog.txt" ); 67 68 // Immediately interrupt the loading 69 logData.interruptLoading(); 70 71 // and wait for the signal 72 QApplication::exec(); 73 74 // Check we have an empty file 75 QCOMPARE( finishedSpy.count(), 1 ); 76 // TODO: check loadingFinished arg == false 77 QCOMPARE( logData.getNbLine(), 0LL ); 78 QCOMPARE( logData.getMaxLength(), 0 ); 79 QCOMPARE( logData.getFileSize(), 0LL ); 80 81 // Restart the VBL 82 logData.attachFile( TMPDIR "/verybiglog.txt" ); 83 84 // Ensure the counting has started 85 { 86 QMutex mutex; 87 QWaitCondition sleep; 88 // sleep.wait( &mutex, 10 ); 89 } 90 91 // Load the SL (should block until VBL is fully indexed) 92 logData.attachFile( TMPDIR "/smalllog.txt" ); 93 94 // and wait for the 2 signals (one for each file) 95 QApplication::exec(); 96 QApplication::exec(); 97 98 // Check we have the small log loaded 99 QCOMPARE( finishedSpy.count(), 3 ); 100 QCOMPARE( logData.getNbLine(), SL_NB_LINES ); 101 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 102 QCOMPARE( logData.getFileSize(), SL_NB_LINES * (SL_LINE_LENGTH+1LL) ); 103 104 // Restart the VBL again 105 logData.attachFile( TMPDIR "/verybiglog.txt" ); 106 107 // Immediately interrupt the loading 108 logData.interruptLoading(); 109 110 // and wait for the signal 111 QApplication::exec(); 112 113 // Check the small log has been restored 114 QCOMPARE( finishedSpy.count(), 4 ); 115 QCOMPARE( logData.getNbLine(), SL_NB_LINES ); 116 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 117 QCOMPARE( logData.getFileSize(), SL_NB_LINES * (SL_LINE_LENGTH+1LL) ); 118 119 // Disconnect all signals 120 disconnect( &logData, 0 ); 121 } 122 123 void TestLogData::changingFile() 124 { 125 char newLine[90]; 126 LogData logData; 127 128 QSignalSpy finishedSpy( &logData, SIGNAL( loadingFinished( bool ) ) ); 129 QSignalSpy progressSpy( &logData, SIGNAL( loadingProgressed( int ) ) ); 130 QSignalSpy changedSpy( &logData, 131 SIGNAL( fileChanged( LogData::MonitoredFileStatus ) ) ); 132 133 // Register for notification file is loaded 134 connect( &logData, SIGNAL( loadingFinished( bool ) ), 135 this, SLOT( loadingFinished() ) ); 136 137 // Generate a small file 138 QFile file( TMPDIR "/changingfile.txt" ); 139 if ( file.open( QIODevice::WriteOnly ) ) { 140 for (int i = 0; i < 200; i++) { 141 snprintf(newLine, 89, sl_format, i); 142 file.write( newLine, qstrlen(newLine) ); 143 } 144 } 145 file.close(); 146 147 // Start loading it 148 logData.attachFile( TMPDIR "/changingfile.txt" ); 149 150 // and wait for the signal 151 QApplication::exec(); 152 153 // Check we have the small file 154 QCOMPARE( finishedSpy.count(), 1 ); 155 QCOMPARE( logData.getNbLine(), 200LL ); 156 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 157 QCOMPARE( logData.getFileSize(), 200 * (SL_LINE_LENGTH+1LL) ); 158 159 // Add some data to it 160 if ( file.open( QIODevice::Append ) ) { 161 for (int i = 0; i < 200; i++) { 162 snprintf(newLine, 89, sl_format, i); 163 file.write( newLine, qstrlen(newLine) ); 164 } 165 } 166 file.close(); 167 168 // and wait for the signals 169 QApplication::exec(); 170 171 // Check we have a bigger file 172 QCOMPARE( changedSpy.count(), 1 ); 173 QCOMPARE( finishedSpy.count(), 2 ); 174 QCOMPARE( logData.getNbLine(), 400LL ); 175 QCOMPARE( logData.getMaxLength(), SL_LINE_LENGTH ); 176 QCOMPARE( logData.getFileSize(), 400 * (SL_LINE_LENGTH+1LL) ); 177 178 // Truncate the file 179 QVERIFY( file.open( QIODevice::WriteOnly ) ); 180 file.close(); 181 182 // and wait for the signals 183 QApplication::exec(); 184 185 // Check we have an empty file 186 QCOMPARE( changedSpy.count(), 2 ); 187 QCOMPARE( finishedSpy.count(), 3 ); 188 QCOMPARE( logData.getNbLine(), 0LL ); 189 QCOMPARE( logData.getMaxLength(), 0 ); 190 QCOMPARE( logData.getFileSize(), 0LL ); 191 } 192 193 void TestLogData::sequentialRead() 194 { 195 LogData logData; 196 197 // Register for notification file is loaded 198 connect( &logData, SIGNAL( loadingFinished( bool ) ), 199 this, SLOT( loadingFinished() ) ); 200 201 logData.attachFile( TMPDIR "/verybiglog.txt" ); 202 203 // Wait for the loading to be done 204 { 205 QApplication::exec(); 206 } 207 208 // Read all lines sequentially 209 QString s; 210 QBENCHMARK { 211 for (int i = 0; i < VBL_NB_LINES; i++) { 212 s = logData.getLineString(i); 213 } 214 } 215 QCOMPARE( s.length(), VBL_LINE_LENGTH ); 216 } 217 218 void TestLogData::randomPageRead() 219 { 220 LogData logData; 221 222 // Register for notification file is loaded 223 connect( &logData, SIGNAL( loadingFinished( bool ) ), 224 this, SLOT( loadingFinished() ) ); 225 226 logData.attachFile( TMPDIR "/verybiglog.txt" ); 227 // Wait for the loading to be done 228 { 229 QApplication::exec(); 230 } 231 232 QWARN("Starting random page read test"); 233 234 // Read page by page from the beginning and the end, using the QStringList 235 // function 236 QStringList list; 237 QBENCHMARK { 238 for (int page = 0; page < (VBL_NB_LINES/VBL_LINE_PER_PAGE)-1; page++) 239 { 240 list = logData.getLines( page*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 241 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 242 int page_from_end = (VBL_NB_LINES/VBL_LINE_PER_PAGE) - page - 1; 243 list = logData.getLines( page_from_end*VBL_LINE_PER_PAGE, VBL_LINE_PER_PAGE ); 244 QCOMPARE(list.count(), VBL_LINE_PER_PAGE); 245 } 246 } 247 } 248 249 // 250 // Private functions 251 // 252 void TestLogData::loadingFinished() 253 { 254 QApplication::quit(); 255 } 256 257 bool TestLogData::generateDataFiles() 258 { 259 char newLine[90]; 260 261 QFile file( TMPDIR "/verybiglog.txt" ); 262 if ( file.open( QIODevice::WriteOnly ) ) { 263 for (int i = 0; i < VBL_NB_LINES; i++) { 264 snprintf(newLine, 89, vbl_format, i); 265 file.write( newLine, qstrlen(newLine) ); 266 } 267 } 268 else { 269 return false; 270 } 271 file.close(); 272 273 file.setFileName( TMPDIR "/smalllog.txt" ); 274 if ( file.open( QIODevice::WriteOnly ) ) { 275 for (int i = 0; i < SL_NB_LINES; i++) { 276 snprintf(newLine, 89, sl_format, i); 277 file.write( newLine, qstrlen(newLine) ); 278 } 279 } 280 else { 281 return false; 282 } 283 file.close(); 284 285 return true; 286 } 287