|
1 // Copyright (c) 2006-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 <e32math.h> |
|
18 #include <bautils.h> |
|
19 #include <sqldb.h> |
|
20 #include "SqlResourceTester.h" |
|
21 |
|
22 /////////////////////////////////////////////////////////////////////////////////////// |
|
23 |
|
24 #define UNUSED_VAR(a) (a) = (a) |
|
25 |
|
26 RTest TheTest(_L("t_sqlload test")); |
|
27 |
|
28 _LIT(KTestDir, "c:\\test\\"); |
|
29 _LIT(KTestDbName1, "c:\\test\\t_sqlload_1.db"); |
|
30 _LIT(KTestDbName2, "c:\\test\\t_sqlload_2.db"); |
|
31 _LIT(KTestDbName3, "c:\\test\\t_sqlload_3.db"); |
|
32 |
|
33 //Test thread count |
|
34 const TInt KTestThreadCnt = 4; |
|
35 |
|
36 //Test database names |
|
37 const TPtrC KTestDbNames[] = |
|
38 { |
|
39 KTestDbName1(), |
|
40 KTestDbName2(), |
|
41 KTestDbName3() |
|
42 }; |
|
43 |
|
44 //Test database count |
|
45 const TInt KTestDbCnt = sizeof(KTestDbNames) / sizeof(KTestDbNames[0]); |
|
46 |
|
47 //Test duration |
|
48 const TInt KTestDuration = 120;//seconds |
|
49 |
|
50 //Test record count |
|
51 const TInt KRecordCnt = 100; |
|
52 //Record count which will be used in the test SQL queries |
|
53 const TInt KQueriedRecordCnt = 40; |
|
54 //Every SQL query will be processed (stepped) in KTestStepCnt steps. |
|
55 const TInt KTestStepCnt = 4; |
|
56 //RSqlStatement object count which will be used in the tests |
|
57 const TInt KStatementCnt = 10; |
|
58 //Max allowed alive RSqlStatement objects per thread |
|
59 const TInt KMaxStatementPerThread = 30; |
|
60 //Binary data length |
|
61 const TInt KBinDataLen = 2003; |
|
62 |
|
63 /////////////////////////////////////////////////////////////////////////////////////// |
|
64 |
|
65 void DeleteTestFiles() |
|
66 { |
|
67 RSqlDatabase::Delete(KTestDbName3); |
|
68 RSqlDatabase::Delete(KTestDbName2); |
|
69 RSqlDatabase::Delete(KTestDbName1); |
|
70 } |
|
71 |
|
72 /////////////////////////////////////////////////////////////////////////////////////// |
|
73 /////////////////////////////////////////////////////////////////////////////////////// |
|
74 //Test macros and functions |
|
75 void Check1(TInt aValue, TInt aLine, TBool aPrintThreadName = EFalse) |
|
76 { |
|
77 if(!aValue) |
|
78 { |
|
79 DeleteTestFiles(); |
|
80 if(aPrintThreadName) |
|
81 { |
|
82 RThread th; |
|
83 TName name = th.Name(); |
|
84 RDebug::Print(_L("*** Thread %S, Line %d\r\n"), &name, aLine); |
|
85 } |
|
86 else |
|
87 { |
|
88 RDebug::Print(_L("*** Line %d\r\n"), aLine); |
|
89 } |
|
90 TheTest(EFalse, aLine); |
|
91 } |
|
92 } |
|
93 void Check2(TInt aValue, TInt aExpected, TInt aLine, TBool aPrintThreadName = EFalse) |
|
94 { |
|
95 if(aValue != aExpected) |
|
96 { |
|
97 DeleteTestFiles(); |
|
98 if(aPrintThreadName) |
|
99 { |
|
100 RThread th; |
|
101 TName name = th.Name(); |
|
102 RDebug::Print(_L("*** Thread %S, Line %d Expected error: %d, got: %d\r\n"), &name, aLine, aExpected, aValue); |
|
103 } |
|
104 else |
|
105 { |
|
106 RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue); |
|
107 } |
|
108 TheTest(EFalse, aLine); |
|
109 } |
|
110 } |
|
111 #define TEST(arg) ::Check1((arg), __LINE__) |
|
112 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__) |
|
113 #define TTEST(arg) ::Check1((arg), __LINE__, ETrue) |
|
114 #define TTEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__, ETrue) |
|
115 |
|
116 /////////////////////////////////////////////////////////////////////////////////////// |
|
117 |
|
118 void CreateTestDir() |
|
119 { |
|
120 RFs fs; |
|
121 TInt err = fs.Connect(); |
|
122 TEST2(err, KErrNone); |
|
123 |
|
124 err = fs.MkDir(KTestDir); |
|
125 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
126 |
|
127 fs.Close(); |
|
128 } |
|
129 |
|
130 /////////////////////////////////////////////////////////////////////////////////////// |
|
131 |
|
132 void CreateTestDatabases() |
|
133 { |
|
134 HBufC8* recData = HBufC8::New(KBinDataLen * 2 + 50);//"* 2" - hex values for the INSERT SQL statement |
|
135 TEST(recData != NULL); |
|
136 TPtr8 sql = recData->Des(); |
|
137 |
|
138 for(TInt dbIdx=0;dbIdx<KTestDbCnt;++dbIdx) |
|
139 { |
|
140 //Create test database |
|
141 RSqlDatabase db; |
|
142 TInt err = db.Create(KTestDbNames[dbIdx]); |
|
143 TEST2(err, KErrNone); |
|
144 |
|
145 //Create test table |
|
146 _LIT8(KCreateSql, "CREATE TABLE A(F1 INTEGER, F2 BLOB)"); |
|
147 err = db.Exec(KCreateSql); |
|
148 TEST(err >= 0); |
|
149 |
|
150 //Insert records in the test table |
|
151 for(TInt recIdx=1;recIdx<=KRecordCnt;++recIdx) |
|
152 { |
|
153 _LIT8(KInsertSql, "INSERT INTO A(F1, F2) VALUES("); |
|
154 sql.Copy(KInsertSql); |
|
155 sql.AppendNum((TInt64)recIdx); |
|
156 sql.Append(_L(", X'")); |
|
157 for(TInt k=0;k<KBinDataLen;++k) |
|
158 { |
|
159 sql.AppendFormat(_L8("%02X"), recIdx); |
|
160 } |
|
161 sql.Append(_L("')")); |
|
162 err = db.Exec(sql); |
|
163 TEST2(err, 1); |
|
164 } |
|
165 |
|
166 db.Close(); |
|
167 } |
|
168 |
|
169 delete recData; |
|
170 } |
|
171 |
|
172 //Structure used by the test thread function for orginizing its set of test data. |
|
173 struct TSqlStatement |
|
174 { |
|
175 RSqlStatement iObj; |
|
176 TBool iAlive; //Non-zero if iObj is alive |
|
177 TInt iCurIndex; //The number of the current record in the set controlled by iObj statement |
|
178 TInt iEndIndex; //The last record number in the set controlled by iObj statement |
|
179 TInt iCount; //Records count in the set controlled by iObj statement |
|
180 }; |
|
181 |
|
182 typedef RArray<TSqlStatement> RSqlStatementArray; |
|
183 |
|
184 //Inits the random numbers generator. |
|
185 //Opens one of the test databases. |
|
186 void PreTest(RSqlDatabase& aDb, TInt64& aSeed, TName& aThreadName) |
|
187 { |
|
188 RThread currThread; |
|
189 |
|
190 //Init the random numbers generator |
|
191 TTime now; |
|
192 now.UniversalTime(); |
|
193 aSeed = now.Int64() + currThread.Id(); |
|
194 |
|
195 //Open one of the test databases |
|
196 const TInt KDbIndex = Math::Rand(aSeed) % KTestDbCnt; |
|
197 |
|
198 aThreadName = currThread.Name(); |
|
199 RDebug::Print(_L("=== Thread %S, database %S\r\n"), &aThreadName, &KTestDbNames[KDbIndex]); |
|
200 |
|
201 TInt err = aDb.Open(KTestDbNames[KDbIndex]); |
|
202 TTEST2(err, KErrNone); |
|
203 } |
|
204 |
|
205 //Creates N statements, where 0 < N < KStatementCnt |
|
206 TInt CreateStatements(RSqlDatabase& aDb, TInt64& aSeed, RSqlStatementArray& aStmtArray) |
|
207 { |
|
208 TInt stmtCount = Math::Rand(aSeed) % KStatementCnt; |
|
209 if(stmtCount == 0) |
|
210 { |
|
211 stmtCount = 1; |
|
212 } |
|
213 for(TInt i=0;i<stmtCount;++i) |
|
214 { |
|
215 TSqlStatement stmt; |
|
216 stmt.iAlive = EFalse; |
|
217 stmt.iCount = KQueriedRecordCnt; |
|
218 stmt.iCurIndex = Math::Rand(aSeed) % KRecordCnt; |
|
219 if(stmt.iCurIndex == 0) |
|
220 { |
|
221 stmt.iCurIndex = 1; |
|
222 } |
|
223 if(stmt.iCurIndex > (KRecordCnt - KQueriedRecordCnt)) |
|
224 { |
|
225 stmt.iCurIndex = KRecordCnt - KQueriedRecordCnt; |
|
226 } |
|
227 stmt.iEndIndex = stmt.iCurIndex + KQueriedRecordCnt; |
|
228 TBuf8<100> sql; |
|
229 sql.Copy(_L8("SELECT * FROM A WHERE F1 >= ")); |
|
230 sql.AppendNum(stmt.iCurIndex); |
|
231 sql.Append(_L8(" AND F1 < ")); |
|
232 sql.AppendNum(stmt.iEndIndex); |
|
233 TInt err = stmt.iObj.Prepare(aDb, sql); |
|
234 TTEST2(err, KErrNone); |
|
235 stmt.iAlive = ETrue; |
|
236 err = aStmtArray.Append(stmt); |
|
237 TTEST2(err, KErrNone); |
|
238 } |
|
239 return stmtCount; |
|
240 } |
|
241 |
|
242 //For each alive statement object - do (TSqlStatement::iCount / KTestStepCnt) |
|
243 //RSqlStatement::Next() calls. If the Next() call reaches the end - close the statement object. |
|
244 TInt ProcessStatements(RSqlStatementArray& aStmtArray) |
|
245 { |
|
246 const TInt KTotalStmtCount = aStmtArray.Count(); |
|
247 TInt alive = 0; |
|
248 TInt completed = 0; |
|
249 for(TInt k=0;k<KTotalStmtCount;++k) |
|
250 { |
|
251 TSqlStatement& stmt = aStmtArray[k]; |
|
252 if(stmt.iAlive) |
|
253 { |
|
254 ++alive; |
|
255 TInt endIndex = stmt.iCurIndex + stmt.iCount / KTestStepCnt; |
|
256 if(endIndex <= stmt.iEndIndex) |
|
257 { |
|
258 while(stmt.iCurIndex < endIndex) |
|
259 { |
|
260 TInt err = stmt.iObj.Next(); |
|
261 TTEST2(err, KSqlAtRow); |
|
262 //test column values |
|
263 TInt val1 = stmt.iObj.ColumnInt(0); |
|
264 TTEST(val1 == stmt.iCurIndex); |
|
265 RSqlColumnReadStream strm; |
|
266 err = strm.ColumnBinary(stmt.iObj, 1); |
|
267 TTEST2(err, KErrNone); |
|
268 for(TInt ii=0;ii<KBinDataLen;++ii) |
|
269 { |
|
270 TUint8 byte = 0; |
|
271 TRAP(err, byte = strm.ReadUint8L()); |
|
272 TTEST2(err, KErrNone); |
|
273 TTEST(byte == (TUint8)val1); |
|
274 } |
|
275 strm.Close(); |
|
276 ++stmt.iCurIndex; |
|
277 } |
|
278 } |
|
279 if(stmt.iCurIndex >= stmt.iEndIndex) |
|
280 { |
|
281 stmt.iObj.Close(); |
|
282 stmt.iAlive = EFalse; |
|
283 ++completed; |
|
284 } |
|
285 } |
|
286 } |
|
287 return completed; |
|
288 } |
|
289 |
|
290 //Close up to N statements, where 0 < N < KStatementCnt |
|
291 TInt CloseStatements(RSqlStatementArray& aStmtArray, TInt64& aSeed) |
|
292 { |
|
293 TInt stmtCount = Math::Rand(aSeed) % KStatementCnt; |
|
294 if(stmtCount == 0) |
|
295 { |
|
296 stmtCount = 1; |
|
297 } |
|
298 const TInt KTotalStmtCount = aStmtArray.Count(); |
|
299 TInt closed = 0; |
|
300 for(TInt j=0;j<stmtCount;++j) |
|
301 { |
|
302 const TInt KIdx = Math::Rand(aSeed) % KTotalStmtCount; |
|
303 TInt idx = KIdx; |
|
304 while((idx = (++idx % KTotalStmtCount)) != KIdx) |
|
305 { |
|
306 if(aStmtArray[idx].iAlive) |
|
307 { |
|
308 aStmtArray[idx].iObj.Close(); |
|
309 aStmtArray[idx].iAlive = EFalse; |
|
310 ++closed; |
|
311 break; |
|
312 } |
|
313 } |
|
314 } |
|
315 return closed; |
|
316 } |
|
317 |
|
318 //Counts the alive statements |
|
319 TInt AliveStatementsCount(RSqlStatementArray& aStmtArray) |
|
320 { |
|
321 TInt aliveCnt = 0; |
|
322 const TInt KTotalStmtCount = aStmtArray.Count(); |
|
323 for(TInt l=0;l<KTotalStmtCount;++l) |
|
324 { |
|
325 if(aStmtArray[l].iAlive) |
|
326 { |
|
327 ++aliveCnt; |
|
328 } |
|
329 } |
|
330 return aliveCnt; |
|
331 } |
|
332 |
|
333 //Close all alive statements |
|
334 void CloseAllStatements(RSqlStatementArray& aStmtArray) |
|
335 { |
|
336 const TInt KTotalStmtCount = aStmtArray.Count(); |
|
337 for(TInt i=0;i<KTotalStmtCount;++i) |
|
338 { |
|
339 if(aStmtArray[i].iAlive) |
|
340 { |
|
341 aStmtArray[i].iObj.Close(); |
|
342 } |
|
343 } |
|
344 TTEST2(TSqlResourceTester::Count(), 0); |
|
345 } |
|
346 |
|
347 //Removes the already closed statements and compresses the array |
|
348 void RemoveDeadStatements(RSqlStatementArray& aStmtArray) |
|
349 { |
|
350 for(TInt i=aStmtArray.Count()-1;i>=0;--i) |
|
351 { |
|
352 if(!aStmtArray[i].iAlive) |
|
353 { |
|
354 aStmtArray.Remove(i); |
|
355 } |
|
356 } |
|
357 aStmtArray.Compress(); |
|
358 } |
|
359 |
|
360 //Close statement objects, statements array and the database object |
|
361 TInt PostTest(RSqlDatabase& aDb, RSqlStatementArray& aStmtArray) |
|
362 { |
|
363 TInt statementsAlive = AliveStatementsCount(aStmtArray); |
|
364 CloseAllStatements(aStmtArray); |
|
365 aStmtArray.Close(); |
|
366 aDb.Close(); |
|
367 return statementsAlive; |
|
368 } |
|
369 |
|
370 //Test thread function |
|
371 //The thread function works with a set of TSqlStatement objects |
|
372 //The test consists of 4 steps: |
|
373 //Step 1: the test thread creates m TSqlStatement objects, 0 < m < KStatementCnt. |
|
374 // With each of the created TSqlStatement objects the test thread prepares SELECT SQL query |
|
375 // "SELECT * FROM A WHERE F1 >= K1 AND F1 < K2", where K1 is random generated number, such that: |
|
376 // 0 < K1 < (KRecordCnt - KQueriedRecordCnt) |
|
377 // K2 = K1 + KQueriedRecordCnt |
|
378 // All just created TSqlStatement objects are marked as alive. |
|
379 //Step 2: For each alive TSqlStatement object the test thread calls iObj.Next() method KTestStepCnt times, |
|
380 // KTestStepCnt < KQueriedRecordCnt. |
|
381 // The column values are retrieved and checked. |
|
382 //Step 3: the test thread closes n TSqlStatement objects, 0 < n < KStatementCnt. |
|
383 //Step 4: the test thread counts how many alive TSqlStatement objects are there. |
|
384 // If this count > KMaxStatementPerThread then the test thread closes all alive TSqlStatement objects |
|
385 // to avoid OOM errors during the test. |
|
386 // |
|
387 // Each test thread does steps 1..4 for a period of KTestDuration seconds. |
|
388 // At the end all TSqlStatement objects are closed. |
|
389 // |
|
390 // The idea of the test is to load the SQL server creating several amount of statement and stream objects |
|
391 // and see that it is working stable and without problems. |
|
392 TInt ThreadFunc(void*) |
|
393 { |
|
394 __UHEAP_MARK; |
|
395 |
|
396 CTrapCleanup* tc = CTrapCleanup::New(); |
|
397 TTEST(tc != NULL); |
|
398 |
|
399 TInt64 seed = 0; |
|
400 RSqlDatabase db; |
|
401 TName threadName; |
|
402 RSqlStatementArray statements; |
|
403 |
|
404 //Init the random numbers generator, opens the database |
|
405 PreTest(db, seed, threadName); |
|
406 |
|
407 //Main test loop |
|
408 TInt iteration = 0; |
|
409 TTime currTime; |
|
410 currTime.UniversalTime(); |
|
411 TTime endTime = currTime + TTimeIntervalSeconds(KTestDuration); |
|
412 while(currTime < endTime) |
|
413 { |
|
414 ++iteration; |
|
415 /////////////////////////////////////////////////////////////////////// |
|
416 TInt statementsAliveBegin = statements.Count(); |
|
417 //Step 1: Create N statements, where 0 < N < KStatementCnt |
|
418 TInt statementsCreated = CreateStatements(db, seed, statements); |
|
419 /////////////////////////////////////////////////////////////////////// |
|
420 //Step 2: For each alive statement object - do (TSqlStatement::iCount / KTestStepCnt) |
|
421 // RSqlStatement::Next() calls. If the Next() call reaches the end - close the statement object. |
|
422 TInt statementsCompleted = ProcessStatements(statements); |
|
423 /////////////////////////////////////////////////////////////////////// |
|
424 //Step 3: Close up to N statements, where 0 < N < KStatementCnt |
|
425 TInt statementsClosed = CloseStatements(statements, seed); |
|
426 /////////////////////////////////////////////////////////////////////// |
|
427 //Step 4: If the alive statement count is more than KMaxStatementPerThread, then close them all |
|
428 TInt statementsAliveEnd = AliveStatementsCount(statements); |
|
429 if(statementsAliveEnd > KMaxStatementPerThread) |
|
430 { |
|
431 RDebug::Print(_L("!!! Thread %S, iteration %d, alive %d, close all\r\n"), &threadName, iteration, statementsAliveEnd); |
|
432 CloseAllStatements(statements); |
|
433 statementsAliveEnd = 0; |
|
434 } |
|
435 /////////////////////////////////////////////////////////////////////// |
|
436 RemoveDeadStatements(statements); |
|
437 RDebug::Print(_L("=== Thread %S, iteration % 4d, begin: % 3d, created % 2d, closed % 2d, completed % 2d, end % 3d, \r\n"), |
|
438 &threadName, iteration, statementsAliveBegin, |
|
439 statementsCreated, statementsClosed, statementsCompleted, |
|
440 statementsAliveEnd); |
|
441 currTime.UniversalTime(); |
|
442 } |
|
443 |
|
444 //Close statement objects and the database object |
|
445 TInt statementsAlive = PostTest(db, statements); |
|
446 |
|
447 delete tc; |
|
448 |
|
449 __UHEAP_MARKEND; |
|
450 |
|
451 RDebug::Print(_L("=== Thread %S exit, still alive %d\r\n"), &threadName, statementsAlive); |
|
452 |
|
453 return KErrNone; |
|
454 } |
|
455 |
|
456 void CreateTestThreads(RThread aThreads[], TRequestStatus aStatuses[], TInt aMaxCount) |
|
457 { |
|
458 _LIT(KThreadName, "TstThr"); |
|
459 for(TInt i=0;i<aMaxCount;++i) |
|
460 { |
|
461 TBuf<20> threadName(KThreadName); |
|
462 threadName.AppendNum((TInt64)(i + 1)); |
|
463 TEST2(aThreads[i].Create(threadName, &ThreadFunc, 0x2000, 0x1000, 0x10000, NULL, EOwnerProcess), KErrNone); |
|
464 aThreads[i].Logon(aStatuses[i]); |
|
465 TEST2(aStatuses[i].Int(), KRequestPending); |
|
466 } |
|
467 } |
|
468 |
|
469 void ResumeTestThreads(RThread aThreads[], TInt aMaxCount) |
|
470 { |
|
471 for(TInt i=0;i<aMaxCount;++i) |
|
472 { |
|
473 aThreads[i].Resume(); |
|
474 } |
|
475 } |
|
476 |
|
477 |
|
478 void CloseTestThreads(RThread aThreads[], TRequestStatus aStatuses[], TInt aMaxCount) |
|
479 { |
|
480 for(TInt i=0;i<aMaxCount;++i) |
|
481 { |
|
482 User::WaitForRequest(aStatuses[i]); |
|
483 TEST(aThreads[i].ExitType() != EExitPanic); |
|
484 aThreads[i].Close(); |
|
485 } |
|
486 } |
|
487 |
|
488 /** |
|
489 @SYMTestCaseID SYSLIB-SQL-CT-1627-0001 |
|
490 @SYMTestCaseDesc SQL server load test. The test creates KTestThreadCnt threads, KTestDbCnt test databases and |
|
491 inserts in each of them KRecordCnt test records. |
|
492 Pre-test step: each test thread randomly chooses and opens one of the test databases. |
|
493 Then, each of the test threads is doing the following 4 test steps: |
|
494 Step 1: the test thread creates m TSqlStatement objects, 0 < m < KStatementCnt. |
|
495 With each of the created TSqlStatement objects the test thread prepares SELECT SQL query |
|
496 "SELECT * FROM A WHERE F1 >= K1 AND F1 < K2", where K1 is random generated number, such that: |
|
497 0 < K1 < (KRecordCnt - KQueriedRecordCnt) |
|
498 K2 = K1 + KQueriedRecordCnt |
|
499 All just created TSqlStatement objects are marked as alive. |
|
500 Step 2: For each alive TSqlStatement object the test thread calls iObj.Next() method KTestStepCnt times, |
|
501 KTestStepCnt < KQueriedRecordCnt. |
|
502 The column values are retrieved and checked. |
|
503 Step 3: the test thread closes n TSqlStatement objects, 0 < n < KStatementCnt. |
|
504 Step 4: the test thread counts how many alive TSqlStatement objects are there. |
|
505 If this count > KMaxStatementPerThread then the test thread closes all alive TSqlStatement objects |
|
506 to avoid OOM errors during the test. |
|
507 |
|
508 Each test thread does steps 1..4 for a period of KTestDuration seconds. |
|
509 At the end all TSqlStatement objects are closed. |
|
510 |
|
511 The idea of the test is to load the SQL server creating several amount of statement and stream objects |
|
512 and see that it is working stable and without problems. |
|
513 @SYMTestPriority High |
|
514 @SYMTestActions SQL server load test |
|
515 @SYMTestExpectedResults Test must not fail |
|
516 @SYMREQ REQ5792 |
|
517 REQ5793 |
|
518 */ |
|
519 void SqlLoadTest() |
|
520 { |
|
521 CreateTestDatabases(); |
|
522 |
|
523 RThread threads[KTestThreadCnt]; |
|
524 TRequestStatus statuses[KTestThreadCnt]; |
|
525 |
|
526 CreateTestThreads(threads, statuses, KTestThreadCnt); |
|
527 |
|
528 ResumeTestThreads(threads, KTestThreadCnt); |
|
529 |
|
530 User::After(2000000); |
|
531 |
|
532 CloseTestThreads(threads, statuses, KTestThreadCnt); |
|
533 } |
|
534 |
|
535 void DoTests() |
|
536 { |
|
537 TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-1627-0001 SQL server load test ")); |
|
538 SqlLoadTest(); |
|
539 } |
|
540 |
|
541 TInt E32Main() |
|
542 { |
|
543 TheTest.Title(); |
|
544 |
|
545 CTrapCleanup* tc = CTrapCleanup::New(); |
|
546 |
|
547 __UHEAP_MARK; |
|
548 |
|
549 CreateTestDir(); |
|
550 DeleteTestFiles(); |
|
551 DoTests(); |
|
552 DeleteTestFiles(); |
|
553 |
|
554 __UHEAP_MARKEND; |
|
555 |
|
556 TheTest.End(); |
|
557 TheTest.Close(); |
|
558 |
|
559 delete tc; |
|
560 |
|
561 User::Heap().Check(); |
|
562 return KErrNone; |
|
563 } |