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 int VBL_NB_LINES = 4999999; 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 int SL_NB_LINES = 5000; 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 // First try to log a non existent file 37 QVERIFY( logData.attachFile( "/non/existent/file" ) == false ); 38 39 // Register for notification file is loaded 40 connect( &logData, SIGNAL( loadingFinished() ), 41 this, SLOT( loadingFinished() ) ); 42 43 QBENCHMARK { 44 QVERIFY( logData.attachFile( TMPDIR "/verybiglog.txt" ) ); 45 // Wait for the loading to be done 46 { 47 QApplication::exec(); 48 } 49 } 50 QCOMPARE( (qint64) progressSpy.count(), logData.getFileSize() / (5LL*1024*1024) + 1 ); 51 QCOMPARE( logData.getNbLine(), VBL_NB_LINES ); 52 QCOMPARE( logData.getMaxLength(), VBL_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() ) ); 63 64 // Register for notification file is loaded 65 connect( &logData, SIGNAL( loadingFinished() ), 66 this, SLOT( loadingFinished() ) ); 67 68 // Start loading the VBL 69 QVERIFY( 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 QCOMPARE( logData.getNbLine(), 0 ); 80 QCOMPARE( logData.getMaxLength(), 0 ); 81 QCOMPARE( logData.getFileSize(), 0LL ); 82 83 // Restart the VBL 84 QVERIFY( 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 QVERIFY( 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 QVERIFY( 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() ) ); 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() ), 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 QVERIFY( 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(), 200 ); 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(), 400 ); 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(), 0 ); 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() ), 201 this, SLOT( loadingFinished() ) ); 202 203 logData.attachFile( TMPDIR "/verybiglog.txt" ); 204 // Wait for the loading to be done 205 { 206 QApplication::exec(); 207 } 208 209 // Read all lines sequentially 210 QString s; 211 QBENCHMARK { 212 for (int i = 0; i < VBL_NB_LINES; i++) { 213 s = logData.getLineString(i); 214 } 215 } 216 QCOMPARE( s.length(), VBL_LINE_LENGTH ); 217 } 218 219 #if 0 220 void TestLogData::randomPageRead() 221 { 222 LogData* logData; 223 224 { 225 QByteArray array = generateData(); 226 logData = new LogData(array); 227 } 228 229 // Read page by page from the beginning and the end 230 QString s; 231 QBENCHMARK { 232 for (int page = 0; page < (NB_LINES/LINE_PER_PAGE)-1; page++) 233 { 234 for (int i = page*LINE_PER_PAGE; i < ((page+1)*LINE_PER_PAGE); i++) 235 s = logData->getLineString(i); 236 int page_from_end = (NB_LINES/LINE_PER_PAGE) - page - 1; 237 for (int i = page_from_end*LINE_PER_PAGE; i < ((page_from_end+1)*LINE_PER_PAGE); i++) 238 s = logData->getLineString(i); 239 } 240 } 241 QVERIFY(s.length() > 0); 242 243 delete logData; 244 } 245 #endif 246 247 // 248 // Private functions 249 // 250 void TestLogData::loadingFinished() 251 { 252 QApplication::quit(); 253 } 254 255 bool TestLogData::generateDataFiles() 256 { 257 char newLine[90]; 258 259 QFile file( TMPDIR "/verybiglog.txt" ); 260 if ( file.open( QIODevice::WriteOnly ) ) { 261 for (int i = 0; i < VBL_NB_LINES; i++) { 262 snprintf(newLine, 89, vbl_format, i); 263 file.write( newLine, qstrlen(newLine) ); 264 } 265 } 266 else { 267 return false; 268 } 269 file.close(); 270 271 file.setFileName( TMPDIR "/smalllog.txt" ); 272 if ( file.open( QIODevice::WriteOnly ) ) { 273 for (int i = 0; i < SL_NB_LINES; i++) { 274 snprintf(newLine, 89, sl_format, i); 275 file.write( newLine, qstrlen(newLine) ); 276 } 277 } 278 else { 279 return false; 280 } 281 file.close(); 282 283 return true; 284 } 285