|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <e32test.h> |
|
17 #include <bautils.h> |
|
18 #include <sqldb.h> |
|
19 #include <stdlib.h> |
|
20 #include "sqlite3.h" |
|
21 #include "SqliteSymbian.h" |
|
22 #include "SqlResourceTester.h" |
|
23 |
|
24 /////////////////////////////////////////////////////////////////////////////////////// |
|
25 |
|
26 RTest TheTest(_L("t_sqlcompact4 test")); |
|
27 TParse TheParse; |
|
28 TDriveName TheDrive; |
|
29 |
|
30 RSqlDatabase TheDb; |
|
31 sqlite3* TheSqliteDb = NULL; |
|
32 TBuf<256> TheCmd; |
|
33 |
|
34 const TInt KTextLen = 1000; |
|
35 const TInt KRecLen = 2000; |
|
36 |
|
37 TBuf<KTextLen> TheText; |
|
38 TBuf8<KRecLen> TheSqlQuery; |
|
39 TBuf8<KRecLen> TheSqlFmt; |
|
40 TBuf<KTextLen + 50> TheSqlTexLen; |
|
41 |
|
42 _LIT(KDefaultDriveName, "c:"); |
|
43 _LIT(KTestDir, "c:\\test\\"); |
|
44 _LIT(KTestDbTemplate8, "c:\\test\\t_sqlcompact4_tmpl8.dat"); |
|
45 _LIT(KTestDbTemplate16, "c:\\test\\t_sqlcompact4_tmpl16.dat"); |
|
46 _LIT(KDbName, "c:\\test\\t_sqlcompact4_1.db"); |
|
47 _LIT(KDbName2, "c:\\test\\t_sqlcompact4_2.db"); |
|
48 _LIT(KRoDbName, "z:\\test\\testdb1.db");//Created outside the test app |
|
49 TFileName TheTestDbName; |
|
50 |
|
51 const TInt KMaxThreadCount = 100; |
|
52 TInt32 TheTestThreadCount = 8; |
|
53 |
|
54 const TInt KTestDbPageSize = 1024; |
|
55 |
|
56 TInt TheOriginalDbSize8 = -1; |
|
57 TInt TheCompactedDbSize8 = -1; |
|
58 |
|
59 TInt TheOriginalDbSize16 = -1; |
|
60 TInt TheCompactedDbSize16 = -1; |
|
61 |
|
62 //In order to be able to compile the test, the following variables are defined (used inside the OS porting layer, when _SQLPROFILER macro is defined) |
|
63 #ifdef _SQLPROFILER |
|
64 TInt TheSqlSrvProfilerFileRead = 0; |
|
65 TInt TheSqlSrvProfilerFileWrite = 0; |
|
66 TInt TheSqlSrvProfilerFileSync = 0; |
|
67 TInt TheSqlSrvProfilerFileSetSize = 0; |
|
68 #endif |
|
69 |
|
70 /////////////////////////////////////////////////////////////////////////////////////// |
|
71 |
|
72 void DestroyTestEnv() |
|
73 { |
|
74 if(TheSqliteDb) |
|
75 { |
|
76 sqlite3_close(TheSqliteDb); |
|
77 TheSqliteDb = NULL; |
|
78 } |
|
79 TheDb.Close(); |
|
80 (void)RSqlDatabase::Delete(KDbName2); |
|
81 (void)RSqlDatabase::Delete(TheTestDbName); |
|
82 (void)RSqlDatabase::Delete(KTestDbTemplate16); |
|
83 (void)RSqlDatabase::Delete(KTestDbTemplate8); |
|
84 sqlite3SymbianLibFinalize(); |
|
85 CloseSTDLIB(); |
|
86 } |
|
87 |
|
88 /////////////////////////////////////////////////////////////////////////////////////// |
|
89 /////////////////////////////////////////////////////////////////////////////////////// |
|
90 //Test macros and functions |
|
91 void Check(TInt aValue, TInt aLine) |
|
92 { |
|
93 if(!aValue) |
|
94 { |
|
95 DestroyTestEnv(); |
|
96 RDebug::Print(_L("*** Test failure. Boolean expression evaluates to false.\r\n")); |
|
97 TheTest(EFalse, aLine); |
|
98 } |
|
99 } |
|
100 void Check(TInt aValue, TInt aExpected, TInt aLine) |
|
101 { |
|
102 if(aValue != aExpected) |
|
103 { |
|
104 DestroyTestEnv(); |
|
105 RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); |
|
106 TheTest(EFalse, aLine); |
|
107 } |
|
108 } |
|
109 #define TEST(arg) ::Check((arg), __LINE__) |
|
110 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) |
|
111 |
|
112 /////////////////////////////////////////////////////////////////////////////////////// |
|
113 |
|
114 void CreateTestEnv() |
|
115 { |
|
116 RFs fs; |
|
117 TInt err = fs.Connect(); |
|
118 TEST2(err, KErrNone); |
|
119 |
|
120 err = fs.MkDir(KTestDir); |
|
121 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
122 |
|
123 TheParse.Set(TheDrive, &KTestDir, 0); |
|
124 |
|
125 err = fs.MkDir(TheParse.DriveAndPath()); |
|
126 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
127 |
|
128 fs.Close(); |
|
129 |
|
130 sqlite3SymbianLibInit(); |
|
131 } |
|
132 |
|
133 /////////////////////////////////////////////////////////////////////////////////////// |
|
134 |
|
135 void CreateTestDatabase8() |
|
136 { |
|
137 TheTest.Printf(_L("Create UTF8 test database: %S\r\n"), &KTestDbTemplate8); |
|
138 (void)RSqlDatabase::Delete(KTestDbTemplate8); |
|
139 TBuf8<KMaxFileName> fname; |
|
140 fname.Copy(KTestDbTemplate8); |
|
141 TheSqliteDb = NULL; |
|
142 TInt rc = sqlite3_open((const char*)fname.PtrZ(), &TheSqliteDb); |
|
143 TEST2(rc, SQLITE_OK); |
|
144 TBuf8<100> sql; |
|
145 _LIT8(KSql, "PRAGMA page_size=%d\x0"); |
|
146 sql.Format(KSql, KTestDbPageSize); |
|
147 rc = sqlite3_exec(TheSqliteDb, (const char*)sql.Ptr(), 0, 0, 0); |
|
148 TEST2(rc, SQLITE_OK); |
|
149 rc = sqlite3_exec(TheSqliteDb, "CREATE TABLE A(Id INTEGER,Data BLOB)", 0, 0, 0); |
|
150 TEST2(rc, SQLITE_OK); |
|
151 //Insert records |
|
152 rc = sqlite3_exec(TheSqliteDb, "BEGIN", 0, 0, 0); |
|
153 TEST2(rc, SQLITE_OK); |
|
154 TheSqlQuery.Copy(_L8("INSERT INTO A VALUES(%d,x'")); |
|
155 for(TInt j=0;j<(KRecLen-50);++j) |
|
156 { |
|
157 TheSqlQuery.Append(_L8("A")); |
|
158 } |
|
159 TheSqlQuery.Append(_L8("')")); |
|
160 const TInt KRecCount = 100; |
|
161 for(TInt i=0;i<KRecCount;++i) |
|
162 { |
|
163 TheSqlFmt.Format(TheSqlQuery, i + 1); |
|
164 rc = sqlite3_exec(TheSqliteDb, (const char*)TheSqlFmt.PtrZ(), 0, 0, 0); |
|
165 TEST2(rc, SQLITE_OK); |
|
166 } |
|
167 rc = sqlite3_exec(TheSqliteDb, "COMMIT", 0, 0, 0); |
|
168 TEST2(rc, SQLITE_OK); |
|
169 //Free some space |
|
170 rc = sqlite3_exec(TheSqliteDb, "DELETE FROM A WHERE Id > 10", 0, 0, 0); |
|
171 TEST2(rc, SQLITE_OK); |
|
172 sqlite3_close(TheSqliteDb); |
|
173 TheSqliteDb = NULL; |
|
174 } |
|
175 |
|
176 void CreateTestDatabase16() |
|
177 { |
|
178 TheTest.Printf(_L("Create UTF16 test database: %S\r\n"), &KTestDbTemplate16); |
|
179 (void)RSqlDatabase::Delete(KTestDbTemplate16); |
|
180 TBuf<KMaxFileName> fname; |
|
181 fname.Copy(KTestDbTemplate16); |
|
182 TheSqliteDb = NULL; |
|
183 TInt rc = sqlite3_open16(fname.PtrZ(), &TheSqliteDb); |
|
184 TEST2(rc, SQLITE_OK); |
|
185 TBuf8<100> sql; |
|
186 _LIT8(KSql, "PRAGMA page_size=%d\x0"); |
|
187 sql.Format(KSql, KTestDbPageSize); |
|
188 rc = sqlite3_exec(TheSqliteDb, (const char*)sql.Ptr(), 0, 0, 0); |
|
189 TEST2(rc, SQLITE_OK); |
|
190 rc = sqlite3_exec(TheSqliteDb, "CREATE TABLE A(Id INTEGER,Data BLOB)", 0, 0, 0); |
|
191 TEST2(rc, SQLITE_OK); |
|
192 //Insert records |
|
193 rc = sqlite3_exec(TheSqliteDb, "BEGIN", 0, 0, 0); |
|
194 TEST2(rc, SQLITE_OK); |
|
195 TheSqlQuery.Copy(_L8("INSERT INTO A VALUES(%d,x'")); |
|
196 for(TInt j=0;j<(KRecLen-50);++j) |
|
197 { |
|
198 TheSqlQuery.Append(_L8("A")); |
|
199 } |
|
200 TheSqlQuery.Append(_L8("')")); |
|
201 const TInt KRecCount = 100; |
|
202 for(TInt i=0;i<KRecCount;++i) |
|
203 { |
|
204 TheSqlFmt.Format(TheSqlQuery, i + 1); |
|
205 rc = sqlite3_exec(TheSqliteDb, (const char*)TheSqlFmt.PtrZ(), 0, 0, 0); |
|
206 TEST2(rc, SQLITE_OK); |
|
207 } |
|
208 rc = sqlite3_exec(TheSqliteDb, "COMMIT", 0, 0, 0); |
|
209 TEST2(rc, SQLITE_OK); |
|
210 //Free some space |
|
211 rc = sqlite3_exec(TheSqliteDb, "DELETE FROM A WHERE Id > 10", 0, 0, 0); |
|
212 TEST2(rc, SQLITE_OK); |
|
213 sqlite3_close(TheSqliteDb); |
|
214 TheSqliteDb = NULL; |
|
215 } |
|
216 |
|
217 void CreateDatabase8(const TDesC& aTargetDbName) |
|
218 { |
|
219 RFs fs; |
|
220 TInt err = fs.Connect(); |
|
221 TEST2(err, KErrNone); |
|
222 CFileMan* fm = NULL; |
|
223 TRAP(err, fm = CFileMan::NewL(fs)); |
|
224 TEST2(err, KErrNone); |
|
225 err = fm->Copy(KTestDbTemplate8, aTargetDbName); |
|
226 delete fm; |
|
227 fs.Close(); |
|
228 TEST2(err, KErrNone); |
|
229 } |
|
230 |
|
231 void CreateDatabase16(const TDesC& aTargetDbName) |
|
232 { |
|
233 RFs fs; |
|
234 TInt err = fs.Connect(); |
|
235 TEST2(err, KErrNone); |
|
236 CFileMan* fm = NULL; |
|
237 TRAP(err, fm = CFileMan::NewL(fs)); |
|
238 TEST2(err, KErrNone); |
|
239 err = fm->Copy(KTestDbTemplate16, aTargetDbName); |
|
240 delete fm; |
|
241 fs.Close(); |
|
242 TEST2(err, KErrNone); |
|
243 } |
|
244 |
|
245 void CalculateMaxCompaction8() |
|
246 { |
|
247 TheTest.Printf(_L("UTF8 test database - calculate max compaction\r\n")); |
|
248 (void)RSqlDatabase::Delete(TheTestDbName); |
|
249 CreateDatabase8(TheTestDbName); |
|
250 TInt err = TheDb.Open(TheTestDbName); |
|
251 TEST2(err, KErrNone); |
|
252 RSqlDatabase::TSize size1; |
|
253 err = TheDb.Size(size1); |
|
254 TEST2(err, KErrNone); |
|
255 TheTest.Printf(_L("UTF8.Database before compaction: size %ld, free space %ld\r\n"), size1.iSize, size1.iFree); |
|
256 err = TheDb.Compact(RSqlDatabase::EMaxCompaction); |
|
257 TEST2(err, size1.iFree); |
|
258 RSqlDatabase::TSize size2; |
|
259 err = TheDb.Size(size2); |
|
260 TEST2(err, KErrNone); |
|
261 TheTest.Printf(_L("UTF8.Database after compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree); |
|
262 TheDb.Close(); |
|
263 (void)RSqlDatabase::Delete(TheTestDbName); |
|
264 TheOriginalDbSize8 = size1.iSize; |
|
265 TheCompactedDbSize8 = size2.iSize; |
|
266 TEST(TheOriginalDbSize8 > 0); |
|
267 TEST(TheCompactedDbSize8 > 0 && TheCompactedDbSize8 < TheOriginalDbSize8); |
|
268 } |
|
269 |
|
270 void CalculateMaxCompaction16() |
|
271 { |
|
272 TheTest.Printf(_L("UTF16 test database - calculate max compaction\r\n")); |
|
273 (void)RSqlDatabase::Delete(TheTestDbName); |
|
274 CreateDatabase16(TheTestDbName); |
|
275 TInt err = TheDb.Open(TheTestDbName); |
|
276 TEST2(err, KErrNone); |
|
277 RSqlDatabase::TSize size1; |
|
278 err = TheDb.Size(size1); |
|
279 TEST2(err, KErrNone); |
|
280 TheTest.Printf(_L("UTF16.Database before compaction: size %ld, free space %ld\r\n"), size1.iSize, size1.iFree); |
|
281 err = TheDb.Compact(RSqlDatabase::EMaxCompaction); |
|
282 TEST2(err, size1.iFree); |
|
283 RSqlDatabase::TSize size2; |
|
284 err = TheDb.Size(size2); |
|
285 TEST2(err, KErrNone); |
|
286 TheTest.Printf(_L("UTF16.Database after compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree); |
|
287 TheDb.Close(); |
|
288 (void)RSqlDatabase::Delete(TheTestDbName); |
|
289 TheOriginalDbSize16 = size1.iSize; |
|
290 TheCompactedDbSize16 = size2.iSize; |
|
291 TEST(TheOriginalDbSize16 > 0); |
|
292 TEST(TheCompactedDbSize16 > 0 && TheCompactedDbSize16 < TheOriginalDbSize16); |
|
293 } |
|
294 |
|
295 /////////////////////////////////////////////////////////////////////////////////////// |
|
296 |
|
297 |
|
298 enum TCompactionType {ESyncCompaction, EAsyncCompaction, EMaxCompactionType}; |
|
299 |
|
300 TInt DoCompact(TCompactionType aType, TInt aSize, const TDesC& aAttachDbName = KNullDesC) |
|
301 { |
|
302 TInt err = KErrGeneral; |
|
303 switch(aType) |
|
304 { |
|
305 case ESyncCompaction: |
|
306 err = TheDb.Compact(aSize, aAttachDbName); |
|
307 break; |
|
308 case EAsyncCompaction: |
|
309 { |
|
310 TRequestStatus stat; |
|
311 TheDb.Compact(aSize, stat, aAttachDbName); |
|
312 User::WaitForRequest(stat); |
|
313 TEST(stat != KRequestPending); |
|
314 err = stat.Int(); |
|
315 break; |
|
316 } |
|
317 default: |
|
318 TEST(0); |
|
319 break; |
|
320 } |
|
321 return err; |
|
322 } |
|
323 |
|
324 TInt DoManualCompaction(TCompactionType aType, const TDesC& aMainDb, TInt aSize, TBool aRoFlag = EFalse) |
|
325 { |
|
326 if(!aRoFlag) |
|
327 { |
|
328 (void)RSqlDatabase::Delete(aMainDb); |
|
329 CreateDatabase8(aMainDb); |
|
330 } |
|
331 |
|
332 TInt err = TheDb.Open(aMainDb); |
|
333 TEST2(err, KErrNone); |
|
334 |
|
335 err = DoCompact(aType, aSize); |
|
336 |
|
337 TheDb.Close(); |
|
338 if(!aRoFlag) |
|
339 { |
|
340 (void)RSqlDatabase::Delete(aMainDb); |
|
341 } |
|
342 return err; |
|
343 } |
|
344 |
|
345 TInt DoManualCompaction(TCompactionType aType, TInt aSize, const TDesC& aAttachDbName) |
|
346 { |
|
347 return DoCompact(aType, aSize, aAttachDbName); |
|
348 } |
|
349 |
|
350 void DoManualCompaction(TCompactionType aType, TInt aSize, TInt aCompactedSize) |
|
351 { |
|
352 (void)RSqlDatabase::Delete(TheTestDbName); |
|
353 CreateDatabase8(TheTestDbName); |
|
354 |
|
355 TInt err = TheDb.Open(TheTestDbName); |
|
356 TEST2(err, KErrNone); |
|
357 |
|
358 err = DoCompact(aType, aSize); |
|
359 TEST(err >= 0); |
|
360 |
|
361 RSqlDatabase::TSize size; |
|
362 err = TheDb.Size(size); |
|
363 TEST2(err, KErrNone); |
|
364 TEST2(size.iSize, aCompactedSize); |
|
365 |
|
366 TheDb.Close(); |
|
367 (void)RSqlDatabase::Delete(TheTestDbName); |
|
368 } |
|
369 |
|
370 void DoManualCompaction(TCompactionType aType, TInt aSize, TInt aCompactedSize, const TDesC& aAttachDbName) |
|
371 { |
|
372 TInt err = DoCompact(aType, aSize, aAttachDbName); |
|
373 TEST(err >= 0); |
|
374 |
|
375 RSqlDatabase::TSize size; |
|
376 err = TheDb.Size(size, aAttachDbName); |
|
377 TEST2(err, KErrNone); |
|
378 TEST2(size.iSize, aCompactedSize); |
|
379 } |
|
380 |
|
381 /** |
|
382 @SYMTestCaseID SYSLIB-SQL-UT-4064 |
|
383 @SYMTestCaseDesc Manual compaction - negative tests. |
|
384 The test creates a database with a manual compaction mode. |
|
385 Then the test executes the following negative tests using both synchronous and |
|
386 asynchronous Compact() methods: |
|
387 - RSqlDatabase::Compact() called with aSize parameter value = KMinTInt; |
|
388 - RSqlDatabase::Compact() called with negative aSize parameter value; |
|
389 - RSqlDatabase::Compact() called on a read-only database; |
|
390 - RSqlDatabase::Compact() called on an attached read-only database; |
|
391 - RSqlDatabase::Compact() called on a nonexisting attached database with very long name; |
|
392 - RSqlDatabase::Compact() called with aSize = 0; |
|
393 - RSqlDatabase::Compact() called on a read-only database where the version number of symbian_settings table is 3; |
|
394 @SYMTestPriority Medium |
|
395 @SYMTestActions Manual compaction - negative tests. |
|
396 @SYMTestExpectedResults Test must not fail |
|
397 @SYMREQ REQ10273 |
|
398 REQ10274 |
|
399 REQ10402 |
|
400 */ |
|
401 void ManualCompactionNegativeTest() |
|
402 { |
|
403 for(TInt i=0;i<EMaxCompactionType;++i) |
|
404 { |
|
405 //Specifying KMaxTInt as aSize argument value. |
|
406 TInt err = DoManualCompaction((TCompactionType)i, TheTestDbName, KMaxTInt); |
|
407 TEST(err > 0); |
|
408 //Specifying KMinTInt as aSize argument value. |
|
409 err = DoManualCompaction((TCompactionType)i, TheTestDbName, KMinTInt); |
|
410 TEST2(err, KErrArgument); |
|
411 //Specifying another negative value as aSize argument value. |
|
412 err = DoManualCompaction((TCompactionType)i, TheTestDbName, -357); |
|
413 TEST2(err, KErrArgument); |
|
414 //Specifying zero as aSize argument value. |
|
415 err = DoManualCompaction((TCompactionType)i, TheTestDbName, 0); |
|
416 TEST2(err, 0); |
|
417 //Read-only database - old format (version 3 of symbian_settings table) |
|
418 err = DoManualCompaction((TCompactionType)i, KRoDbName, RSqlDatabase::EMaxCompaction, ETrue); |
|
419 TEST2(err, KSqlErrReadOnly); |
|
420 // |
|
421 (void)RSqlDatabase::Delete(TheTestDbName); |
|
422 CreateDatabase16(TheTestDbName); |
|
423 err = TheDb.Open(TheTestDbName); |
|
424 TEST2(err, KErrNone); |
|
425 _LIT(KAttachDbName, "Db"); |
|
426 //Attached read-only database |
|
427 err = TheDb.Attach(KRoDbName, KAttachDbName); |
|
428 TEST2(err, KErrNone); |
|
429 err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, KAttachDbName); |
|
430 TEST2(err, KSqlErrReadOnly); |
|
431 err = TheDb.Detach(KAttachDbName); |
|
432 TEST2(err, KErrNone); |
|
433 //Nonexisting attached database |
|
434 err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, _L("aaa")); |
|
435 TEST2(err, KSqlErrGeneral); |
|
436 //Very long name of a nonexisting attached database |
|
437 TBuf<KMaxFileName + 10> fname; |
|
438 fname.SetLength(fname.MaxLength()); |
|
439 fname.Fill(0xDD); |
|
440 err = DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, fname); |
|
441 TEST2(err, KErrBadName); |
|
442 // |
|
443 TheDb.Close(); |
|
444 (void)RSqlDatabase::Delete(TheTestDbName); |
|
445 } |
|
446 } |
|
447 |
|
448 /** |
|
449 @SYMTestCaseID SYSLIB-SQL-UT-4065 |
|
450 @SYMTestCaseDesc Manual compaction - functional tests. |
|
451 The test creates a database with a manual compaction mode. |
|
452 Then the test executes the following functional tests using both synchronous and |
|
453 asynchronous Compact() methods: |
|
454 - RSqlDatabase::Compact() called with aSize parameter value = RSqlDatabase::EMaxCompaction; |
|
455 - RSqlDatabase::Compact() called with aSize parameter value = 0. No pages should be removed; |
|
456 - RSqlDatabase::Compact() called with aSize parameter value = 1. 1 page should be removed; |
|
457 - RSqlDatabase::Compact() called with aSize parameter value = "db page size - 1". 1 page should be removed; |
|
458 - RSqlDatabase::Compact() called with aSize parameter value = "db page size * <cnt>". <cnt> pages should be removed; |
|
459 - RSqlDatabase::Compact() called with aSize parameter value > the free db space. All free pages should be removed; |
|
460 The same functional tests are repeated with an attached database. |
|
461 @SYMTestPriority Medium |
|
462 @SYMTestActions Manual compaction - functional tests. |
|
463 @SYMTestExpectedResults Test must not fail |
|
464 @SYMREQ REQ10273 |
|
465 REQ10274 |
|
466 REQ10402 |
|
467 */ |
|
468 void ManualCompactionTest() |
|
469 { |
|
470 for(TInt i=0;i<EMaxCompactionType;++i) |
|
471 { |
|
472 //Calling Compact() with aSize = RSqlDatabase::EMaxCompaction |
|
473 DoManualCompaction((TCompactionType)i, RSqlDatabase::EMaxCompaction, TheCompactedDbSize8); |
|
474 //Calling Compact() with aSize = 0. 0 pages expected to be removed |
|
475 DoManualCompaction((TCompactionType)i, 0, TheOriginalDbSize8); |
|
476 //Calling Compact() with aSize = 1. 1 page expected to be removed |
|
477 DoManualCompaction((TCompactionType)i, 1, TheOriginalDbSize8 - KTestDbPageSize); |
|
478 //Calling Compact() with aSize = KTestDbPageSize - 1. 1 page expected to be removed |
|
479 DoManualCompaction((TCompactionType)i, KTestDbPageSize - 1, TheOriginalDbSize8 - KTestDbPageSize); |
|
480 //Calling Compact() with aSize = KTestDbPageSize. 1 page expected to be removed |
|
481 DoManualCompaction((TCompactionType)i, KTestDbPageSize, TheOriginalDbSize8 - KTestDbPageSize); |
|
482 const TInt KPagesCnt1 = 17; |
|
483 //Calling Compact() with aSize = KTestDbPageSize * KPagesCnt1. KPagesCnt1 pages expected to be removed |
|
484 DoManualCompaction((TCompactionType)i, KTestDbPageSize * KPagesCnt1, TheOriginalDbSize8 - KTestDbPageSize * KPagesCnt1); |
|
485 //Calling Compact() with aSize > TheOriginalDbSize8. All free pages expected to be removed |
|
486 DoManualCompaction((TCompactionType)i, TheOriginalDbSize8 + 2000, TheCompactedDbSize8); |
|
487 //Attached database |
|
488 (void)RSqlDatabase::Delete(KDbName2); |
|
489 TInt err = TheDb.Create(KDbName2); |
|
490 TEST2(err, KErrNone); |
|
491 (void)RSqlDatabase::Delete(TheTestDbName); |
|
492 CreateDatabase16(TheTestDbName); |
|
493 _LIT(KAttachDbName, "Db"); |
|
494 err = TheDb.Attach(TheTestDbName, KAttachDbName); |
|
495 TEST2(err, KErrNone); |
|
496 TInt newDatabaseSize = TheOriginalDbSize16; |
|
497 //Calling Compact() with aSize = 0. 0 pages expected to be removed |
|
498 DoManualCompaction((TCompactionType)i, 0, newDatabaseSize, KAttachDbName); |
|
499 //Calling Compact() with aSize = 1. 1 page expected to be removed |
|
500 DoManualCompaction((TCompactionType)i, 1, TheOriginalDbSize16 - KTestDbPageSize, KAttachDbName); |
|
501 newDatabaseSize -= KTestDbPageSize; |
|
502 //Calling Compact() with aSize = KTestDbPageSize - 1. 1 page expected to be removed |
|
503 DoManualCompaction((TCompactionType)i, KTestDbPageSize - 1, newDatabaseSize - KTestDbPageSize, KAttachDbName); |
|
504 newDatabaseSize -= KTestDbPageSize; |
|
505 //Calling Compact() with aSize = KTestDbPageSize. 1 page expected to be removed |
|
506 DoManualCompaction((TCompactionType)i, KTestDbPageSize, newDatabaseSize - KTestDbPageSize, KAttachDbName); |
|
507 newDatabaseSize -= KTestDbPageSize; |
|
508 //Calling Compact() with aSize = KTestDbPageSize * KPagesCnt1. KPagesCnt1 pages expected to be removed |
|
509 DoManualCompaction((TCompactionType)i, KTestDbPageSize * KPagesCnt1, newDatabaseSize - KTestDbPageSize * KPagesCnt1, KAttachDbName); |
|
510 newDatabaseSize -= KTestDbPageSize * KPagesCnt1; |
|
511 //Calling Compact() with aSize > newDatabaseSize. All free pages expected to be removed |
|
512 DoManualCompaction((TCompactionType)i, newDatabaseSize + 2000, TheCompactedDbSize16, KAttachDbName); |
|
513 // |
|
514 err = TheDb.Detach(KAttachDbName); |
|
515 TEST2(err, KErrNone); |
|
516 TheDb.Close(); |
|
517 (void)RSqlDatabase::Delete(KDbName2); |
|
518 } |
|
519 } |
|
520 |
|
521 |
|
522 enum TSizeTestType {EManualSizeTest, EAutoSizeTest}; |
|
523 |
|
524 void DoCompactionDbSizeTest(TSizeTestType aType) |
|
525 { |
|
526 (void)RSqlDatabase::Delete(TheTestDbName); |
|
527 _LIT8(KConfig1, "compaction=manual"); |
|
528 _LIT8(KConfig2, "compaction=auto"); |
|
529 TInt err = TheDb.Create(TheTestDbName, aType == EManualSizeTest ? &KConfig1 : &KConfig2); |
|
530 TEST2(err, KErrNone); |
|
531 err = TheDb.Exec(_L("CREATE TABLE A(T TEXT)")); |
|
532 TEST2(err, 1); |
|
533 // |
|
534 RSqlDatabase::TSize size; |
|
535 err = TheDb.Size(size); |
|
536 TEST2(err, KErrNone); |
|
537 TEST2(size.iFree, 0); |
|
538 // |
|
539 const TInt KRecCnt = 50; |
|
540 for(TInt i=0;i<KRecCnt;++i) |
|
541 { |
|
542 err = TheDb.Exec(_L("INSERT INTO A VALUES('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaa')")); |
|
543 TEST2(err, 1); |
|
544 } |
|
545 // |
|
546 err = TheDb.Size(size); |
|
547 TEST2(err, KErrNone); |
|
548 TEST2(size.iFree, 0); |
|
549 // |
|
550 err = TheDb.Exec(_L("DELETE FROM A WHERE 1")); |
|
551 TEST2(err, KRecCnt); |
|
552 // |
|
553 err = TheDb.Size(size); |
|
554 TEST2(err, KErrNone); |
|
555 if(aType == EManualSizeTest) |
|
556 { |
|
557 TEST(size.iFree > 0); |
|
558 } |
|
559 else |
|
560 { |
|
561 TEST2(size.iFree, 0); |
|
562 } |
|
563 // |
|
564 TheDb.Close(); |
|
565 (void)RSqlDatabase::Delete(TheTestDbName); |
|
566 } |
|
567 |
|
568 /** |
|
569 @SYMTestCaseID SYSLIB-SQL-UT-4066 |
|
570 @SYMTestCaseDesc RSqlDatabase::Size(TSize&) called on a database with manual compaction mode. |
|
571 The test creates a database with a manual compaction mode. |
|
572 Then the test inserts some records and deletes the records making some free database pages. |
|
573 The test calls RSqlDatabase::Size(TSize&) before and after the delete operation and verifies |
|
574 that the database file size stays unchanged. |
|
575 @SYMTestPriority Medium |
|
576 @SYMTestActions RSqlDatabase::Size(TSize&) called on a database with manual compaction mode. |
|
577 @SYMTestExpectedResults Test must not fail |
|
578 @SYMREQ REQ10407 |
|
579 */ |
|
580 void ManualCompactionSizeTest() |
|
581 { |
|
582 DoCompactionDbSizeTest(EManualSizeTest); |
|
583 } |
|
584 |
|
585 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
586 ////////////////////////////////// OOM testing //////////////////////////////////////////////////////////// |
|
587 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
588 |
|
589 void PrintEndOfOomTest(TInt aFailingAllocationNo) |
|
590 { |
|
591 TheTest.Printf(_L("=== OOM Test succeeded at heap failure rate of %d ===\r\n"), aFailingAllocationNo); |
|
592 } |
|
593 |
|
594 void SetDbHeapFailure(TInt aFailingAllocationNo) |
|
595 { |
|
596 const TInt KDelayedDbHeapFailureMask = 0x1000; |
|
597 TSqlResourceTester::SetDbHeapFailure(RHeap::EDeterministic | KDelayedDbHeapFailureMask, aFailingAllocationNo); |
|
598 } |
|
599 |
|
600 void ResetDbHeapFailure() |
|
601 { |
|
602 TSqlResourceTester::SetDbHeapFailure(RHeap::ENone, 0); |
|
603 } |
|
604 |
|
605 static TInt TheHandleCount1B; |
|
606 static TInt TheHandleCount2B; |
|
607 static TInt TheAllocatedCellsCountB; |
|
608 |
|
609 void MarkHandles() |
|
610 { |
|
611 RThread().HandleCount(TheHandleCount1B, TheHandleCount2B); |
|
612 } |
|
613 |
|
614 void CheckHandles() |
|
615 { |
|
616 TInt endHandleCount1E; |
|
617 TInt endHandleCount2E; |
|
618 |
|
619 RThread().HandleCount(endHandleCount1E, endHandleCount2E); |
|
620 |
|
621 TEST(TheHandleCount1B == endHandleCount1E); |
|
622 TEST(TheHandleCount2B == endHandleCount2E); |
|
623 } |
|
624 |
|
625 void MarkAllocatedCells() |
|
626 { |
|
627 TheAllocatedCellsCountB = User::CountAllocCells(); |
|
628 } |
|
629 |
|
630 void CheckAllocatedCells() |
|
631 { |
|
632 TInt allocatedCellsCountE = User::CountAllocCells(); |
|
633 TEST(allocatedCellsCountE == TheAllocatedCellsCountB); |
|
634 } |
|
635 |
|
636 typedef void (*TDbFuncPtrL)(const TDesC& aDbName); |
|
637 |
|
638 void DoManualCompactionOomTest(TDbFuncPtrL aTestFunctionPtrL, const TDesC& aDbFileName, const TDesC& aAttachDbFileName, const TDesC& aDbName) |
|
639 { |
|
640 const TInt KDoDbOomTestAllocLimitServer = 1000; |
|
641 TInt failingAllocation = 0; |
|
642 TInt allocation = 0; |
|
643 TInt err = KErrNoMemory; |
|
644 while(allocation < KDoDbOomTestAllocLimitServer) |
|
645 { |
|
646 MarkHandles(); |
|
647 MarkAllocatedCells(); |
|
648 |
|
649 __UHEAP_MARK; |
|
650 |
|
651 SetDbHeapFailure(++allocation); |
|
652 |
|
653 err = TheDb.Open(aDbFileName); |
|
654 TEST2(err, KErrNone); |
|
655 if(aAttachDbFileName != KNullDesC) |
|
656 { |
|
657 TEST(aDbName != KNullDesC); |
|
658 err = TheDb.Attach(aAttachDbFileName, aDbName); |
|
659 TEST(err == KErrNone || err == KErrNoMemory); |
|
660 } |
|
661 if(err == KErrNone) |
|
662 { |
|
663 TRAP(err, (*aTestFunctionPtrL)(aDbName)); |
|
664 if(err != KErrNoMemory) |
|
665 { |
|
666 TEST2(err, KErrNone); |
|
667 } |
|
668 else |
|
669 { |
|
670 failingAllocation = allocation; |
|
671 } |
|
672 } |
|
673 |
|
674 ResetDbHeapFailure(); |
|
675 |
|
676 if(aAttachDbFileName != KNullDesC) |
|
677 { |
|
678 (void)TheDb.Detach(aDbName); |
|
679 } |
|
680 TheDb.Close(); |
|
681 |
|
682 __UHEAP_MARKEND; |
|
683 |
|
684 CheckAllocatedCells(); |
|
685 CheckHandles(); |
|
686 } |
|
687 TEST2(err, KErrNone); |
|
688 PrintEndOfOomTest(failingAllocation + 1); |
|
689 } |
|
690 |
|
691 void OomTest1L(const TDesC&) |
|
692 { |
|
693 User::LeaveIfError(TheDb.Compact(RSqlDatabase::EMaxCompaction)); |
|
694 } |
|
695 |
|
696 void OomTest2L(const TDesC& aDbName) |
|
697 { |
|
698 TEST(aDbName != KNullDesC); |
|
699 User::LeaveIfError(TheDb.Compact(RSqlDatabase::EMaxCompaction, aDbName)); |
|
700 } |
|
701 |
|
702 /** |
|
703 @SYMTestCaseID SYSLIB-SQL-UT-4068 |
|
704 @SYMTestCaseDesc RSqlDatabase::Compact() - OOM test. |
|
705 The test creates a database with a manual compaction mode. |
|
706 Then the test calls Compact() in an OOM loop. |
|
707 The same OOM test is repeated for Compact() called an attached database. |
|
708 @SYMTestPriority Medium |
|
709 @SYMTestActions RSqlDatabase::Compact() - OOM test. |
|
710 @SYMTestExpectedResults Test must not fail |
|
711 @SYMREQ REQ10405 |
|
712 */ |
|
713 void ManualCompactionOomTest() |
|
714 { |
|
715 TheTest.Printf(_L("Main database - manual compaction - OOM test\r\n")); |
|
716 (void)RSqlDatabase::Delete(TheTestDbName); |
|
717 CreateDatabase8(TheTestDbName); |
|
718 DoManualCompactionOomTest(&OomTest1L, TheTestDbName, KNullDesC, KNullDesC); |
|
719 TInt err = TheDb.Open(TheTestDbName); |
|
720 TEST2(err, KErrNone); |
|
721 RSqlDatabase::TSize size; |
|
722 err = TheDb.Size(size); |
|
723 TEST2(err, KErrNone); |
|
724 TEST2(size.iSize, TheCompactedDbSize8); |
|
725 TheDb.Close(); |
|
726 |
|
727 TheTest.Printf(_L("Attached database - manual compaction - OOM test\r\n")); |
|
728 (void)RSqlDatabase::Delete(KDbName2); |
|
729 err = TheDb.Create(KDbName2); |
|
730 TEST2(err, KErrNone); |
|
731 TheDb.Close(); |
|
732 (void)RSqlDatabase::Delete(TheTestDbName); |
|
733 CreateDatabase16(TheTestDbName); |
|
734 DoManualCompactionOomTest(&OomTest2L, KDbName2, TheTestDbName, _L("Db")); |
|
735 err = TheDb.Open(TheTestDbName); |
|
736 TEST2(err, KErrNone); |
|
737 err = TheDb.Size(size); |
|
738 TEST2(err, KErrNone); |
|
739 TEST2(size.iSize, TheCompactedDbSize16); |
|
740 TheDb.Close(); |
|
741 |
|
742 (void)RSqlDatabase::Delete(KDbName2); |
|
743 (void)RSqlDatabase::Delete(TheTestDbName); |
|
744 } |
|
745 |
|
746 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
747 |
|
748 /** |
|
749 @SYMTestCaseID SYSLIB-SQL-UT-4067 |
|
750 @SYMTestCaseDesc RSqlDatabase::Size(TSize&) called on a database with auto compaction mode. |
|
751 The test creates a database with an auto compaction mode. |
|
752 Then the test inserts some records and deletes the records. |
|
753 The test calls RSqlDatabase::Size(TSize&) after the delete operation and verifies |
|
754 that the database file does not contain any free pages. |
|
755 @SYMTestPriority Medium |
|
756 @SYMTestActions RSqlDatabase::Size(TSize&) called on a database with auto compaction mode. |
|
757 @SYMTestExpectedResults Test must not fail |
|
758 @SYMREQ REQ10407 |
|
759 REQ10400 |
|
760 */ |
|
761 void AutoCompactionSizeTest() |
|
762 { |
|
763 DoCompactionDbSizeTest(EAutoSizeTest); |
|
764 } |
|
765 |
|
766 /** |
|
767 @SYMTestCaseID SYSLIB-SQL-UT-4069 |
|
768 @SYMTestCaseDesc Background compaction functional test. |
|
769 The test executes a 10 iterations loop with a "sleep" time 1000000 us at the beginning. |
|
770 The "sleep" time is divided by 2 on each iteration. |
|
771 In each iteration the test creates a database with free pages count big enough to kick-off the |
|
772 background compaction. Then the test executes enough Exec()s in order to kick-off the background compaction. |
|
773 Then the test "sleeps" the calculated "sleep" time and checks after that the database size and free pages |
|
774 count and prints them out. After the last iteration the same test is repeated with no "sleep" time. |
|
775 The test verifies how the client connection activity affects the possibility of the server to run the |
|
776 background compaction. |
|
777 @SYMTestPriority Medium |
|
778 @SYMTestActions Background compaction functional test. |
|
779 @SYMTestExpectedResults Test must not fail |
|
780 @SYMREQ REQ10271 |
|
781 REQ10407 |
|
782 */ |
|
783 void BackgroundCompactionTest() |
|
784 { |
|
785 TInt interval = 1000000;//us |
|
786 const TInt KIterationCnt = 10; |
|
787 TheTest.Printf(_L("===Sleep after Exec()\r\n")); |
|
788 for(TInt i=0;i<KIterationCnt;++i) |
|
789 { |
|
790 (void)RSqlDatabase::Delete(TheTestDbName); |
|
791 CreateDatabase8(TheTestDbName); |
|
792 TInt err = TheDb.Open(TheTestDbName); |
|
793 TEST2(err, KErrNone); |
|
794 RSqlDatabase::TSize size1; |
|
795 err = TheDb.Size(size1); |
|
796 TEST2(err, KErrNone); |
|
797 TheTest.Printf(_L("---------------------------------\r\n")); |
|
798 TheTest.Printf(_L("===Sleep time %d ms. Database before background compaction: size %ld, free space %ld\r\n"), interval / 1000, size1.iSize, size1.iFree); |
|
799 //Simulate Exec() activities |
|
800 for(TInt j=0;j<100;++j) |
|
801 { |
|
802 err = TheDb.Exec(_L8("SELECT Id FROM A LIMIT 1")); |
|
803 TEST(err >= 0); |
|
804 } |
|
805 User::After(interval); |
|
806 RSqlDatabase::TSize size2; |
|
807 err = TheDb.Size(size2); |
|
808 TEST2(err, KErrNone); |
|
809 TheTest.Printf(_L("===Database after background compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree); |
|
810 TEST(size2.iSize <= size1.iSize); |
|
811 TEST(size2.iFree <= size1.iFree); |
|
812 interval /= 2; |
|
813 TheDb.Close(); |
|
814 } |
|
815 TheTest.Printf(_L("===No sleep\r\n")); |
|
816 (void)RSqlDatabase::Delete(TheTestDbName); |
|
817 CreateDatabase8(TheTestDbName); |
|
818 TInt err = TheDb.Open(TheTestDbName); |
|
819 TEST2(err, KErrNone); |
|
820 RSqlDatabase::TSize size1; |
|
821 err = TheDb.Size(size1); |
|
822 TEST2(err, KErrNone); |
|
823 TheTest.Printf(_L("===Database before background compaction: size %ld, free space %ld\r\n"), size1.iSize, size1.iFree); |
|
824 //Simulate Exec() activities |
|
825 for(TInt j=0;j<100;++j) |
|
826 { |
|
827 err = TheDb.Exec(_L8("SELECT Id FROM A LIMIT 1")); |
|
828 TEST(err >= 0); |
|
829 } |
|
830 RSqlDatabase::TSize size2; |
|
831 err = TheDb.Size(size2); |
|
832 TEST2(err, KErrNone); |
|
833 TheTest.Printf(_L("===Database after background compaction: size %ld, free space %ld\r\n"), size2.iSize, size2.iFree); |
|
834 TEST(size2.iSize <= size1.iSize); |
|
835 TEST(size2.iFree <= size1.iFree); |
|
836 TheDb.Close(); |
|
837 (void)RSqlDatabase::Delete(TheTestDbName); |
|
838 } |
|
839 |
|
840 struct TThreadData |
|
841 { |
|
842 TThreadData(const TDesC& aFileName, TInt aSleepInterval) : |
|
843 iDbName(aFileName), |
|
844 iSleepInterval(aSleepInterval) |
|
845 { |
|
846 TInt err = iCritSection.CreateLocal(); |
|
847 TEST2(err, KErrNone); |
|
848 iCritSection.Wait(); |
|
849 Mem::FillZ(&iSize1, sizeof(iSize1)); |
|
850 Mem::FillZ(&iSize2, sizeof(iSize2)); |
|
851 } |
|
852 TFileName iDbName; |
|
853 RCriticalSection iCritSection; |
|
854 RSqlDatabase::TSize iSize1; |
|
855 RSqlDatabase::TSize iSize2; |
|
856 TInt iSleepInterval; |
|
857 }; |
|
858 |
|
859 TInt ThreadFunc(void* aPrm) |
|
860 { |
|
861 TEST(aPrm != NULL); |
|
862 |
|
863 __UHEAP_MARK; |
|
864 CTrapCleanup* tc = CTrapCleanup::New(); |
|
865 TheTest(tc != NULL); |
|
866 |
|
867 //Wait for a signal from the main thread |
|
868 TThreadData* thrdat = (TThreadData*)aPrm; |
|
869 thrdat->iCritSection.Wait(); |
|
870 |
|
871 RSqlDatabase db; |
|
872 TInt err = db.Open(thrdat->iDbName); |
|
873 TEST2(err, KErrNone); |
|
874 err = db.Size(thrdat->iSize1); |
|
875 TEST2(err, KErrNone); |
|
876 //Simulate Exec() activities |
|
877 for(TInt j=0;j<100;++j) |
|
878 { |
|
879 err = db.Exec(_L8("SELECT Id FROM A LIMIT 1")); |
|
880 TEST(err >= 0); |
|
881 if((j % 10) == 0 && thrdat->iSleepInterval > 0) |
|
882 { |
|
883 User::After(thrdat->iSleepInterval); |
|
884 } |
|
885 } |
|
886 err = db.Size(thrdat->iSize2); |
|
887 TEST2(err, KErrNone); |
|
888 db.Close(); |
|
889 |
|
890 delete tc; |
|
891 __UHEAP_MARKEND; |
|
892 return KErrNone; |
|
893 } |
|
894 |
|
895 /** |
|
896 @SYMTestCaseID SYSLIB-SQL-UT-4070 |
|
897 @SYMTestCaseDesc Background compaction load test. |
|
898 The test runs 8 threads. Each thread connects to a different database. |
|
899 Each database has space in the free pages above the "free pages" threshold - |
|
900 the background compaction will be scheduled at the moment when the database is opened. |
|
901 Every thread executes some operations on the opened database - that will delay the background compaction. |
|
902 After every 10 operations the thread sleeps for a specified interval of a time. |
|
903 After all threads complete, the test checks the database size and free pages count and |
|
904 prints them out. |
|
905 The test verifies the ability of the SQL server to run the background compaction under a load. |
|
906 @SYMTestPriority Medium |
|
907 @SYMTestActions Background compaction load test. |
|
908 @SYMTestExpectedResults Test must not fail |
|
909 @SYMREQ REQ10271 |
|
910 REQ10407 |
|
911 */ |
|
912 void BackgroundCompactionLoadTest() |
|
913 { |
|
914 RThread threads[KMaxThreadCount]; |
|
915 TThreadData* thrdata[KMaxThreadCount] = {NULL}; |
|
916 TRequestStatus thrstat[KMaxThreadCount]; |
|
917 |
|
918 const TInt KSleepInterval[] = {0, 50000, 100000, 300000, 500000, 800000};//us |
|
919 const TInt KTestCnt = sizeof(KSleepInterval) / sizeof(KSleepInterval[0]); |
|
920 |
|
921 for(TInt k=0;k<KTestCnt;++k) |
|
922 { |
|
923 TheTest.Printf(_L("=================================================\r\n")); |
|
924 TheTest.Printf(_L("===Sleep interval %d ms\r\n"), KSleepInterval[k] / 1000); |
|
925 TheTest.Printf(_L("=================================================\r\n")); |
|
926 //Create test databases and threads |
|
927 for(TInt i=0;i<TheTestThreadCount;++i) |
|
928 { |
|
929 //Database |
|
930 TBuf<16> fname; |
|
931 fname.Copy(_L("\\test\\a")); |
|
932 fname.AppendNum(i + 1); |
|
933 fname.Append(_L(".db")); |
|
934 TheParse.Set(TheDrive, &fname, 0); |
|
935 (void)RSqlDatabase::Delete(TheParse.FullName()); |
|
936 CreateDatabase8(TheParse.FullName()); |
|
937 //Thread data |
|
938 thrdata[i] = new TThreadData(TheParse.FullName(), KSleepInterval[k]); |
|
939 TEST(thrdata[i] != NULL); |
|
940 //Thread |
|
941 TBuf<16> thrname; |
|
942 thrname.Copy(_L("Thread")); |
|
943 thrname.AppendNum(i + 1); |
|
944 TInt err = threads[i].Create(thrname, &ThreadFunc, 0x2000, 0x1000, 0x10000, thrdata[i], EOwnerProcess); |
|
945 TEST2(err, KErrNone); |
|
946 threads[i].Logon(thrstat[i]); |
|
947 TEST2(thrstat[i].Int(), KRequestPending); |
|
948 threads[i].Resume(); |
|
949 } |
|
950 //Enable the threads |
|
951 for(TInt i=0;i<TheTestThreadCount;++i) |
|
952 { |
|
953 thrdata[i]->iCritSection.Signal(); |
|
954 } |
|
955 //Wait for cmpletion |
|
956 for(TInt i=0;i<TheTestThreadCount;++i) |
|
957 { |
|
958 User::WaitForRequest(thrstat[i]); |
|
959 } |
|
960 //Report |
|
961 for(TInt i=0;i<TheTestThreadCount;++i) |
|
962 { |
|
963 TheTest.Printf(_L("===Thread %d, database %S\r\n"), i + 1, &(thrdata[i]->iDbName)); |
|
964 TheTest.Printf(_L("===Before background compaction: size %6ld, free space %6ld\r\n"), thrdata[i]->iSize1.iSize, thrdata[i]->iSize1.iFree); |
|
965 TheTest.Printf(_L("===After background compaction: size %6ld, free space %6ld\r\n"), thrdata[i]->iSize2.iSize, thrdata[i]->iSize2.iFree); |
|
966 TEST(thrdata[i]->iSize2.iSize <= thrdata[i]->iSize1.iSize); |
|
967 TEST(thrdata[i]->iSize2.iFree <= thrdata[i]->iSize1.iFree); |
|
968 } |
|
969 //Destroy |
|
970 for(TInt i=0;i<TheTestThreadCount;++i) |
|
971 { |
|
972 (void)RSqlDatabase::Delete(thrdata[i]->iDbName); |
|
973 thrdata[i]->iCritSection.Close(); |
|
974 delete thrdata[i]; |
|
975 thrdata[i] = NULL; |
|
976 CLOSE_AND_WAIT(threads[i]); |
|
977 } |
|
978 } |
|
979 } |
|
980 |
|
981 /** |
|
982 @SYMTestCaseID SYSLIB-SQL-UT-4071 |
|
983 @SYMTestCaseDesc Background compaction in a DDL transaction test. |
|
984 The test creates a database, begins a transaction that modifies the database structure |
|
985 and executes enough operations in order free enough space to kick-off the background compaction. |
|
986 The test should not report any failures caused by the fact that the main database connection is |
|
987 in a DML transaction and at the same time the background connection may try to execute |
|
988 a "PRAGMA freelist_count" statement. |
|
989 @SYMTestPriority Medium |
|
990 @SYMTestActions Background compaction in a DDL transaction test. |
|
991 @SYMTestExpectedResults Test must not fail |
|
992 @SYMREQ REQ10271 |
|
993 */ |
|
994 void BackgroundCompactionInDDLTransactionTest() |
|
995 { |
|
996 const TInt KOperationCount = 100; |
|
997 (void)RSqlDatabase::Delete(KDbName); |
|
998 TInt err = TheDb.Create(KDbName); |
|
999 TEST2(err, KErrNone); |
|
1000 err = TheDb.Exec(_L("BEGIN")); |
|
1001 TEST(err >= 0); |
|
1002 err = TheDb.Exec(_L("CREATE TABLE A(I INTEGER, T TEXT)")); |
|
1003 TEST2(err, 1); |
|
1004 TheText.SetLength(KTextLen); |
|
1005 TheText.Fill(TChar('A')); |
|
1006 for(TInt i=0;i<=KOperationCount;++i) |
|
1007 { |
|
1008 TheSqlTexLen.Format(_L("INSERT INTO A VALUES(%d, '%S')"), i + 1, &TheText); |
|
1009 err = TheDb.Exec(TheSqlTexLen); |
|
1010 TEST2(err, 1); |
|
1011 } |
|
1012 err = TheDb.Exec(_L("COMMIT")); |
|
1013 TEST(err >= 0); |
|
1014 TheDb.Close(); |
|
1015 (void)RSqlDatabase::Delete(KDbName); |
|
1016 } |
|
1017 |
|
1018 void DoTestsL() |
|
1019 { |
|
1020 CreateTestDatabase8(); |
|
1021 CalculateMaxCompaction8(); |
|
1022 CreateTestDatabase16(); |
|
1023 CalculateMaxCompaction16(); |
|
1024 |
|
1025 TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4064 Manual Compact() - negative tests")); |
|
1026 ManualCompactionNegativeTest(); |
|
1027 |
|
1028 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4065 Manual Compact() tests")); |
|
1029 ManualCompactionTest(); |
|
1030 |
|
1031 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4066 Manual compaction db size test")); |
|
1032 ManualCompactionSizeTest(); |
|
1033 |
|
1034 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4068 Manual compaction - OOM test")); |
|
1035 ManualCompactionOomTest(); |
|
1036 |
|
1037 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4067 Auto compaction db size test")); |
|
1038 AutoCompactionSizeTest(); |
|
1039 |
|
1040 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4069 Background compaction test")); |
|
1041 BackgroundCompactionTest(); |
|
1042 |
|
1043 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4070 Background compaction - load test")); |
|
1044 BackgroundCompactionLoadTest(); |
|
1045 |
|
1046 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4071 Background compaction activated inside a DDL transaction - test")); |
|
1047 BackgroundCompactionInDDLTransactionTest(); |
|
1048 } |
|
1049 |
|
1050 TInt E32Main() |
|
1051 { |
|
1052 TheTest.Title(); |
|
1053 |
|
1054 CTrapCleanup* tc = CTrapCleanup::New(); |
|
1055 TheTest(tc != NULL); |
|
1056 |
|
1057 TheTest.Printf(_L("Usage:\r\n t_sqlcompact4 [[drive:] [test thread count]]\r\n")); |
|
1058 TheDrive.Copy(KDefaultDriveName); |
|
1059 User::CommandLine(TheCmd); |
|
1060 TheCmd.TrimAll(); |
|
1061 if(TheCmd.Length() > 0) |
|
1062 { |
|
1063 TInt pos = TheCmd.Locate(TChar(' ')); |
|
1064 TheTest(pos > 0); |
|
1065 TPtrC prm1(TheCmd.Left(pos)); |
|
1066 TPtrC prm2(TheCmd.Mid(pos + 1)); |
|
1067 |
|
1068 TheDrive.Copy(prm1); |
|
1069 |
|
1070 TLex lex(prm2); |
|
1071 lex.Val(TheTestThreadCount); |
|
1072 } |
|
1073 TheParse.Set(TheDrive, &KDbName, 0); |
|
1074 TheTestDbName.Copy(TheParse.FullName()); |
|
1075 TheTest.Printf(_L("Test database: %S\r\n"), &TheTestDbName); |
|
1076 |
|
1077 __UHEAP_MARK; |
|
1078 |
|
1079 CreateTestEnv(); |
|
1080 TRAPD(err, DoTestsL()); |
|
1081 DestroyTestEnv(); |
|
1082 TEST2(err, KErrNone); |
|
1083 |
|
1084 __UHEAP_MARKEND; |
|
1085 |
|
1086 TheTest.End(); |
|
1087 TheTest.Close(); |
|
1088 |
|
1089 delete tc; |
|
1090 |
|
1091 User::Heap().Check(); |
|
1092 return KErrNone; |
|
1093 } |