|
1 // Copyright (c) 2005-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 "t_sqloom.h" |
|
17 |
|
18 RTest TheTest(_L("t_sqloom3 test")); |
|
19 |
|
20 /////////////////////////////////////////////////////////////////////////////////////// |
|
21 /////////////// RSqlDatabase OOM tests //////////////////////////////// |
|
22 /////////////////////////////////////////////////////////////////////////////////////// |
|
23 |
|
24 /** |
|
25 @SYMTestCaseID SYSLIB-SQL-CT-1615, SYSLIB-SQL-CT-1639 |
|
26 @SYMTestCaseDesc RSqlDatabase::Create() OOM test - secure and non-secure databases. |
|
27 Precondition: the database does not exist. |
|
28 The test calls RSqlDatabase::Create() while simulating OOM failures and checks |
|
29 that there are no memory and resource leaks. |
|
30 Note: It's possible for a database to be created even after memory allocation |
|
31 has failed. This is because SQLITE reuses some pages of the page cache which |
|
32 have been allocated but are curently not in use. This means it is necessary |
|
33 to delete the database and continue checking for memory and resource leaks |
|
34 even after a database has been created successfully. |
|
35 @SYMTestPriority High |
|
36 @SYMTestActions RSqlDatabase::Create() OOM test |
|
37 @SYMTestExpectedResults Test must not fail |
|
38 @SYMREQ REQ5792 |
|
39 REQ5793 |
|
40 REQ10271 |
|
41 REQ10273 |
|
42 REQ10274 |
|
43 */ |
|
44 void DoCreateDatabaseOomTest(const TDesC& aDbFileName, TDbType aDbType, TInt aExpectedError, const TDesC8* aConfigStr = NULL) |
|
45 { |
|
46 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1639 RSqlDatabase::Create() - OOM test")); |
|
47 RSqlSecurityPolicy securityPolicy; |
|
48 CreateTestSecurityPolicy(securityPolicy); |
|
49 enum TMethodType {ENonLeavingMethod, ELeavingMethod}; |
|
50 const TMethodType KMethodType[] = {ENonLeavingMethod, ELeavingMethod}; |
|
51 for(TInt j=0;j<sizeof(KMethodType)/sizeof(KMethodType[0]);++j) |
|
52 { |
|
53 for(TInt i=0;i<(TInt)(sizeof(TheOomTestType)/sizeof(TheOomTestType[0]));++i) |
|
54 { |
|
55 if(aExpectedError != KErrAlreadyExists) |
|
56 { |
|
57 (void)RSqlDatabase::Delete(aDbFileName); |
|
58 } |
|
59 TInt err = KErrNone; |
|
60 TInt failingAllocationNo = 0; |
|
61 TInt allocationNo = 0; |
|
62 TInt maxAllocationNo = TheOomTestType[i] == EServerSideTest ? KDoCreateDatabaseOomTestAllocLimitServer : KDoCreateDatabaseOomTestAllocLimitClient; |
|
63 while(allocationNo < maxAllocationNo) |
|
64 { |
|
65 MarkHandles(); |
|
66 MarkAllocatedCells(); |
|
67 |
|
68 __UHEAP_MARK; |
|
69 |
|
70 RSqlDatabase db; |
|
71 |
|
72 SetDbHeapFailure(TheOomTestType[i], ++allocationNo); |
|
73 |
|
74 if(KMethodType[j] == ENonLeavingMethod) |
|
75 { |
|
76 err = aDbType == ESecureDb ? db.Create(aDbFileName, securityPolicy, aConfigStr) : db.Create(aDbFileName, aConfigStr); |
|
77 } |
|
78 else |
|
79 { |
|
80 TRAP(err, aDbType == ESecureDb ? db.CreateL(aDbFileName, securityPolicy, aConfigStr) : db.CreateL(aDbFileName, aConfigStr)); |
|
81 } |
|
82 |
|
83 db.Close(); |
|
84 if(err != KErrNoMemory) |
|
85 { |
|
86 TEST2(err, aExpectedError); |
|
87 } |
|
88 else |
|
89 { |
|
90 failingAllocationNo = allocationNo; |
|
91 } |
|
92 |
|
93 ResetDbHeapFailure(TheOomTestType[i]); |
|
94 |
|
95 if(err == KErrNone && aExpectedError != KErrAlreadyExists) |
|
96 { |
|
97 err = db.Delete(aDbFileName); |
|
98 TEST2(err, KErrNone); |
|
99 } |
|
100 |
|
101 __UHEAP_MARKEND; |
|
102 |
|
103 CheckAllocatedCells(); |
|
104 CheckHandles(); |
|
105 } |
|
106 TEST2(err, aExpectedError); |
|
107 PrintEndOfOomTest(TheOomTestType[i], failingAllocationNo + 1); |
|
108 } |
|
109 } |
|
110 RSqlDatabase::Delete(aDbFileName); |
|
111 securityPolicy.Close(); |
|
112 } |
|
113 |
|
114 //"RSqlDatabase::Open()" OOM test |
|
115 void OpenDatabaseL(RSqlDatabase& aDb, const TDesC& aDbFileName, TDbType) |
|
116 { |
|
117 TInt err = aDb.Open(aDbFileName); |
|
118 User::LeaveIfError(err); |
|
119 } |
|
120 |
|
121 //"RSqlDatabase::Exec()" OOM test (8-bit SQL statements), syntax error |
|
122 void ExecBadStatement8L(RSqlDatabase& aDb, const TDesC&, TDbType) |
|
123 { |
|
124 _LIT8(KSqlString, "CREATE TABL BBB(Fld1 INTEGER, Fld2 BIGINT, Fld3 DOUBLE, Fld4 TEXT)"); |
|
125 TInt err = aDb.Exec(KSqlString); |
|
126 User::LeaveIfError(err); |
|
127 } |
|
128 |
|
129 //"RSqlDatabase::Exec()" OOM test (16-bit SQL statements), syntax error |
|
130 void ExecBadStatement16L(RSqlDatabase& aDb, const TDesC&, TDbType) |
|
131 { |
|
132 _LIT(KSqlString, "CREATE TABLE B!B!B(Fld1 INTEGER, Fld2 BIGINT, Fld3 DOUBLE, Fld4 TEXT)"); |
|
133 TInt err = aDb.Exec(KSqlString); |
|
134 User::LeaveIfError(err); |
|
135 } |
|
136 |
|
137 /** |
|
138 @SYMTestCaseID SYSLIB-SQL-CT-1813 |
|
139 @SYMTestCaseDesc RSqlDatabase methods - negative OOM test |
|
140 Precondition: the database exists. |
|
141 The test calls the given as an argument function while simulating OOM failures |
|
142 and checks that there are no memory and resource leaks. The calling function is expected to fail |
|
143 with aExpectedError error. |
|
144 @SYMTestPriority High |
|
145 @SYMTestActions RSqlDatabase methods - negative OOM tests |
|
146 @SYMTestExpectedResults Test must not fail |
|
147 @SYMREQ REQ5792 |
|
148 REQ5793 |
|
149 */ |
|
150 void DoDbOomNegativeTest(TDbFuncPtrL aTestFunctionPtrL, const TDesC& aDbFileName, TDbAction aDbAction, TInt aExpectedError) |
|
151 { |
|
152 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1813 RSqlDatabase - negative OOM test")); |
|
153 for(TInt i=0;i<(TInt)(sizeof(TheOomTestType)/sizeof(TheOomTestType[0]));++i) |
|
154 { |
|
155 TInt err = KErrNoMemory; |
|
156 TInt failingAllocationNo = 0; |
|
157 while(err == KErrNoMemory) |
|
158 { |
|
159 MarkHandles(); |
|
160 MarkAllocatedCells(); |
|
161 |
|
162 __UHEAP_MARK; |
|
163 |
|
164 if(TheOomTestType[i] == EServerSideTest) |
|
165 {//If aDbAction is EOpenDb, then we will delay the heap failure simulation, until the database is opened |
|
166 SetDbHeapFailure(TheOomTestType[i], ++failingAllocationNo, aDbAction == EOpenDb); |
|
167 } |
|
168 |
|
169 RSqlDatabase db; |
|
170 //if aDbAction is EOpenDb then this is a OOM test different than a test for RSqlDatabase::Open |
|
171 if(aDbAction == EOpenDb) |
|
172 { |
|
173 err = db.Open(aDbFileName); |
|
174 TEST2(err, KErrNone); |
|
175 } |
|
176 |
|
177 if(TheOomTestType[i] == EClientSideTest) |
|
178 { |
|
179 SetDbHeapFailure(TheOomTestType[i], ++failingAllocationNo); |
|
180 } |
|
181 |
|
182 TRAP(err, (*aTestFunctionPtrL)(db, aDbFileName, ENonSecureDb)); |
|
183 db.Close(); |
|
184 if(err != KErrNoMemory) |
|
185 { |
|
186 TEST2(err, aExpectedError); |
|
187 } |
|
188 |
|
189 ResetDbHeapFailure(TheOomTestType[i]); |
|
190 |
|
191 __UHEAP_MARKEND; |
|
192 |
|
193 CheckAllocatedCells(); |
|
194 CheckHandles(); |
|
195 } |
|
196 TEST2(err, aExpectedError); |
|
197 PrintEndOfOomTest(TheOomTestType[i], failingAllocationNo); |
|
198 } |
|
199 RSqlDatabase::Delete(aDbFileName); |
|
200 } |
|
201 |
|
202 /////////////////////////////////////////////////////////////////////////////////////// |
|
203 /////////////////////////////////////////////////////////////////////////////////////// |
|
204 |
|
205 //RSqlDatabase - negative OOM tests |
|
206 void DbOomNegativeTestsL() |
|
207 { |
|
208 TheTest.Printf(_L("===RSqlDatabase::Open(), non-existing drive\r\n")); |
|
209 _LIT(KDbName1, "A:[1111CCCC]db1.db"); |
|
210 DoDbOomNegativeTest(&OpenDatabaseL, KDbName1, ENotOpenDb, KErrNotReady); |
|
211 |
|
212 TheTest.Printf(_L("===RSqlDatabase::Open(), non-existing file\r\n")); |
|
213 _LIT(KDbName2, "c:\\test\\nofile.db"); |
|
214 DoDbOomNegativeTest(&OpenDatabaseL, KDbName2, ENotOpenDb, KErrNotFound); |
|
215 |
|
216 TheTest.Printf(_L("===RSqlDatabase::Open(), zero-length name\r\n")); |
|
217 _LIT(KDbName3, ""); |
|
218 DoDbOomNegativeTest(&OpenDatabaseL, KDbName3, ENotOpenDb, KErrBadName); |
|
219 |
|
220 TheTest.Printf(_L("===RSqlDatabase::Open(), directory name\r\n")); |
|
221 _LIT(KDbName4, "C:\\TEST\\"); |
|
222 DoDbOomNegativeTest(&OpenDatabaseL, KDbName4, ENotOpenDb, KErrBadName); |
|
223 |
|
224 TheTest.Printf(_L("===RSqlDatabase::Create(), secure database already exists\r\n")); |
|
225 RSqlSecurityPolicy securityPolicy; |
|
226 CreateTestSecurityPolicy(securityPolicy); |
|
227 RSqlDatabase db; |
|
228 TInt err = db.Create(KSecureDb2, securityPolicy); |
|
229 TEST2(err, KErrNone); |
|
230 db.Close(); |
|
231 securityPolicy.Close(); |
|
232 DoCreateDatabaseOomTest(KSecureDb2, ESecureDb, KErrAlreadyExists); |
|
233 |
|
234 TheTest.Printf(_L("===RSqlDatabase::Create(), database already exists\r\n")); |
|
235 err = db.Create(KTestDb2); |
|
236 TEST2(err, KErrNone); |
|
237 db.Close(); |
|
238 DoCreateDatabaseOomTest(KTestDb2, ENonSecureDb, KErrAlreadyExists); |
|
239 |
|
240 TheTest.Printf(_L("===RSqlDatabase::Exec(), 8-bit SQL, syntax error\r\n")); |
|
241 err = db.Create(KTestDb); |
|
242 TEST2(err, KErrNone); |
|
243 db.Close(); |
|
244 DoDbOomNegativeTest(&ExecBadStatement8L, KTestDb, EOpenDb, KSqlErrGeneral); |
|
245 |
|
246 TheTest.Printf(_L("===RSqlDatabase::Exec(), 16-bit SQL, syntax error\r\n")); |
|
247 err = db.Create(KTestDb); |
|
248 TEST2(err, KErrNone); |
|
249 db.Close(); |
|
250 DoDbOomNegativeTest(&ExecBadStatement16L, KTestDb, EOpenDb, KSqlErrGeneral); |
|
251 } |
|
252 |
|
253 void DEF114297PrepareStmtL(RSqlDatabase& aDb, RSqlStatement& aStmt) |
|
254 { |
|
255 _LIT(KSelectSql, "SELECT e.* FROM edge AS e, node AS n1, node AS n2 WHERE n1.name = 'alice' AND n2.name = 'bob' AND e.orig = n1.id AND e.dest = n2.id ORDER BY n2.name DESC"); |
|
256 TInt err = aStmt.Prepare(aDb, KSelectSql); |
|
257 User::LeaveIfError(err); |
|
258 } |
|
259 |
|
260 /** |
|
261 @SYMTestCaseID SYSLIB-SQL-UT-4004 |
|
262 @SYMTestCaseDesc Test for DEF114297 - SqlSrv.EXE::!SQL Server OOM Test for PrepareL. |
|
263 The test does an OOM test for RSqlStatement::Prepare() using a specific SELECT SQL statement. |
|
264 @SYMTestPriority High |
|
265 @SYMTestActions Test for DEF114297 - SqlSrv.EXE::!SQL Server OOM Test for PrepareL. |
|
266 @SYMTestExpectedResults Test must not fail |
|
267 @SYMDEF DEF114297 |
|
268 */ |
|
269 void DEF114297() |
|
270 { |
|
271 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4004 ===DEF114297 - SqlSrv.EXE::!SQL Server OOM Test for PrepareL ")); |
|
272 (void)RSqlDatabase::Delete(KTestDb); |
|
273 RSqlDatabase db; |
|
274 TInt err = db.Create(KTestDb); |
|
275 TEST2(err, KErrNone); |
|
276 err = db.Exec(_L("CREATE TABLE node(id INTEGER PRIMARY KEY,name TEXT)")); |
|
277 TEST2(err, 1); |
|
278 err = db.Exec(_L("CREATE INDEX node_idx ON node(name)")); |
|
279 TEST2(err, 1); |
|
280 err = db.Exec(_L("CREATE TABLE edge(orig INTEGER REFERENCES node,dest INTEGER REFERENCES node,PRIMARY KEY(orig, dest))")); |
|
281 TEST2(err, 1); |
|
282 err = db.Exec(_L("CREATE INDEX edge_idx ON edge(dest,orig)")); |
|
283 TEST2(err, 1); |
|
284 err = db.Exec(_L("INSERT INTO node(id,name) VALUES(1,'alice')")); |
|
285 TEST2(err, 1); |
|
286 err = db.Exec(_L("INSERT INTO node(id,name) VALUES(2,'bob')")); |
|
287 TEST2(err, 1); |
|
288 err = KErrNoMemory; |
|
289 TInt failingAllocationNo = 0; |
|
290 while(err == KErrNoMemory) |
|
291 { |
|
292 MarkHandles(); |
|
293 MarkAllocatedCells(); |
|
294 |
|
295 __UHEAP_MARK; |
|
296 |
|
297 SetHeapFailure(EServerSideTest, ++failingAllocationNo); |
|
298 |
|
299 RSqlStatement stmt; |
|
300 TRAP(err, DEF114297PrepareStmtL(db, stmt)); |
|
301 stmt.Close(); |
|
302 if(err != KErrNoMemory) |
|
303 { |
|
304 TEST2(err, KErrNone); |
|
305 } |
|
306 |
|
307 ResetHeapFailure(EServerSideTest); |
|
308 |
|
309 __UHEAP_MARKEND; |
|
310 |
|
311 CheckAllocatedCells(); |
|
312 CheckHandles(); |
|
313 } |
|
314 db.Close(); |
|
315 (void)RSqlDatabase::Delete(KTestDb); |
|
316 } |
|
317 |
|
318 /** |
|
319 @SYMTestCaseID SYSLIB-SQL-UT-4011 |
|
320 @SYMTestCaseDesc Test for DEF115815 - SELECT random()&1==-1 causes sql server to crash. |
|
321 The test does an OOM test for RSqlStatement::Prepare() using a specific SELECT SQL statement. |
|
322 @SYMTestPriority High |
|
323 @SYMTestActions Test for DEF115815 - SELECT random()&1==-1 causes sql server to crash. |
|
324 @SYMTestExpectedResults Test must not fail |
|
325 @SYMDEF DEF115815 |
|
326 */ |
|
327 void DEF115815() |
|
328 { |
|
329 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-UT-4011 ===DEF115815 - SELECT random()&1==-1 causes sql server to crash ")); |
|
330 (void)RSqlDatabase::Delete(KTestDb); |
|
331 RSqlDatabase db; |
|
332 TInt err = db.Create(KTestDb); |
|
333 TEST2(err, KErrNone); |
|
334 err = db.Exec(_L("CREATE TABLE node(id INTEGER)")); |
|
335 TEST2(err, 1); |
|
336 err = KErrNoMemory; |
|
337 TInt failingAllocationNo = 0; |
|
338 while(err == KErrNoMemory) |
|
339 { |
|
340 MarkHandles(); |
|
341 MarkAllocatedCells(); |
|
342 |
|
343 __UHEAP_MARK; |
|
344 |
|
345 SetHeapFailure(EServerSideTest, ++failingAllocationNo); |
|
346 |
|
347 RSqlStatement stmt; |
|
348 err = stmt.Prepare(db, _L("SELECT random()&1==-1")); |
|
349 stmt.Close(); |
|
350 if(err != KErrNoMemory) |
|
351 { |
|
352 TEST2(err, KErrNone); |
|
353 } |
|
354 |
|
355 ResetHeapFailure(EServerSideTest); |
|
356 |
|
357 __UHEAP_MARKEND; |
|
358 |
|
359 CheckAllocatedCells(); |
|
360 CheckHandles(); |
|
361 } |
|
362 db.Close(); |
|
363 (void)RSqlDatabase::Delete(KTestDb); |
|
364 } |
|
365 |
|
366 void DoTestsL() |
|
367 { |
|
368 TheTest.Start(_L("SQL OOM-3 tests")); |
|
369 |
|
370 DbOomNegativeTestsL(); |
|
371 |
|
372 DEF114297(); |
|
373 |
|
374 DEF115815(); |
|
375 } |
|
376 |
|
377 TInt E32Main() |
|
378 { |
|
379 TheTest.Title(); |
|
380 |
|
381 CTrapCleanup* tc = CTrapCleanup::New(); |
|
382 |
|
383 __UHEAP_MARK; |
|
384 |
|
385 CreateTestDir(); |
|
386 DeleteTestFiles(); |
|
387 |
|
388 TRAPD(err, DoTestsL()); |
|
389 DeleteTestFiles(); |
|
390 TEST2(err, KErrNone); |
|
391 |
|
392 __UHEAP_MARKEND; |
|
393 |
|
394 TheTest.End(); |
|
395 TheTest.Close(); |
|
396 |
|
397 delete tc; |
|
398 |
|
399 User::Heap().Check(); |
|
400 return KErrNone; |
|
401 } |