|
1 // Copyright (c) 2004-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 // Testing new RDbs methods, which handle "Out of disk space" situations. |
|
15 // |
|
16 // |
|
17 |
|
18 #include <e32test.h> |
|
19 #include <f32file.h> |
|
20 #include <d32dbms.h> |
|
21 |
|
22 ///////////////////////////////////////////////////////////////// |
|
23 //Globals |
|
24 |
|
25 //If you change KTestDrive, don't forget to change KTestDatabase too!!! |
|
26 |
|
27 #if defined __WINSCW__ || defined __WINS__ |
|
28 |
|
29 //The C: drive may be too big and may be used concurently by other applications. |
|
30 //The T: drive is more suitable for the test if running on the emulator |
|
31 const TInt KTestDrive = EDriveT; |
|
32 _LIT( KTestDatabase, "T:\\DBMS-TST\\T_DbmsOOD.DB"); |
|
33 |
|
34 #elif defined __X86GCC__ |
|
35 |
|
36 const TInt KTestDrive = EDriveG; |
|
37 _LIT( KTestDatabase, "G:\\DBMS-TST\\T_DbmsOOD.DB"); |
|
38 |
|
39 #else |
|
40 |
|
41 const TInt KTestDrive = EDriveE; |
|
42 _LIT( KTestDatabase, "E:\\DBMS-TST\\T_DbmsOOD.DB"); |
|
43 |
|
44 #endif |
|
45 |
|
46 const TInt KReservedSpaceSize = 0; //The aSpace parameter of RDbs::ReserveDriveSpace() |
|
47 //is not used at the moment and shall be set to 0. |
|
48 |
|
49 static RTest TheTest(_L("t_dbood - \"Out of Disk space\" test")); |
|
50 static RFs TheFs; |
|
51 static RDbNamedDatabase TheDb; |
|
52 static RDbs TheDbSession; |
|
53 |
|
54 //Test table defs |
|
55 _LIT(KTestTableName, "TABLE1"); |
|
56 |
|
57 const TInt KTestRecordsCount = 350; |
|
58 |
|
59 struct TColDef |
|
60 { |
|
61 const TText* iName; |
|
62 TDbColType iType; |
|
63 TInt iAttributes; |
|
64 }; |
|
65 static TColDef const KColDefs[]= |
|
66 { |
|
67 {_S("ID"), EDbColUint32, TDbCol::EAutoIncrement}, |
|
68 {_S("DATA"), EDbColBinary, TDbCol::ENotNull}, |
|
69 {0} |
|
70 }; |
|
71 |
|
72 //One or more files with KLargeFileName name and ".<n>" extension, where n is |
|
73 //000, 001, 002, 003... |
|
74 //will be created and they will occupy almost all available disk space. |
|
75 //The idea is to perform after that "delete" |
|
76 //transaction, which has to fail, because of "out of disk space" condition. |
|
77 #if defined __WINSCW__ || defined __WINS__ |
|
78 |
|
79 _LIT(KLargeFileName, "T:\\DBMS-TST\\DeleteMe"); |
|
80 |
|
81 #elif defined __X86GCC__ |
|
82 |
|
83 _LIT(KLargeFileName, "G:\\DBMS-TST\\DeleteMe"); |
|
84 |
|
85 #else |
|
86 |
|
87 _LIT(KLargeFileName, "E:\\DBMS-TST\\DeleteMe"); |
|
88 |
|
89 #endif |
|
90 |
|
91 static void AssembleLargeFileName(const TDesC& aFileName, TInt aFileNumber, TDes& aResultPath) |
|
92 { |
|
93 _LIT(KFormatStr, "%S.%03d"); |
|
94 aResultPath.Format(KFormatStr, &aFileName, aFileNumber); |
|
95 } |
|
96 |
|
97 /////////////////////////////////////////////////////////////////////////////////////// |
|
98 /////////////////////////////////////////////////////////////////////////////////////// |
|
99 //Create/Destroy test environment - global functions |
|
100 |
|
101 //Deletes "aFullName" file. |
|
102 static TInt DeleteDataFile(const TDesC& aFullName) |
|
103 { |
|
104 RFs fsSession; |
|
105 TInt err = fsSession.Connect(); |
|
106 if(err == KErrNone) |
|
107 { |
|
108 TEntry entry; |
|
109 err = fsSession.Entry(aFullName, entry); |
|
110 if(err == KErrNone) |
|
111 { |
|
112 RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName); |
|
113 err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly); |
|
114 if(err != KErrNone) |
|
115 { |
|
116 RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName); |
|
117 } |
|
118 err = fsSession.Delete(aFullName); |
|
119 if(err != KErrNone) |
|
120 { |
|
121 RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName); |
|
122 } |
|
123 } |
|
124 fsSession.Close(); |
|
125 } |
|
126 else |
|
127 { |
|
128 RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName); |
|
129 } |
|
130 return err; |
|
131 } |
|
132 |
|
133 //Deletes large data files only |
|
134 static void DeleteLargeDataFiles() |
|
135 { |
|
136 for(TInt i=0;i<1000;++i) |
|
137 { |
|
138 TBuf<KMaxFileName> filePath; |
|
139 AssembleLargeFileName(KLargeFileName, i, filePath); |
|
140 if(DeleteDataFile(filePath) != KErrNone) |
|
141 { |
|
142 break; |
|
143 } |
|
144 } |
|
145 } |
|
146 |
|
147 //Deletes data files used by the test |
|
148 static void DeleteDataFiles() |
|
149 { |
|
150 if(TheDbSession.Handle()) |
|
151 { |
|
152 TheDb.Close(); |
|
153 } |
|
154 TheDbSession.Close(); |
|
155 DeleteDataFile(KTestDatabase); |
|
156 DeleteLargeDataFiles(); |
|
157 } |
|
158 |
|
159 /////////////////////////////////////////////////////////////////////////////////////// |
|
160 /////////////////////////////////////////////////////////////////////////////////////// |
|
161 //Tests macros and functions. |
|
162 //If (!aValue) then the test will be panicked, the test data files will be deleted. |
|
163 static void Check(TInt aValue, TInt aLine) |
|
164 { |
|
165 if(!aValue) |
|
166 { |
|
167 DeleteDataFiles(); |
|
168 TheTest(EFalse, aLine); |
|
169 } |
|
170 } |
|
171 //If (aValue != aExpected) then the test will be panicked, the test data files will be deleted. |
|
172 static void Check(TInt aValue, TInt aExpected, TInt aLine) |
|
173 { |
|
174 if(aValue != aExpected) |
|
175 { |
|
176 RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); |
|
177 DeleteDataFiles(); |
|
178 TheTest(EFalse, aLine); |
|
179 } |
|
180 } |
|
181 //Use these to test conditions. |
|
182 #define TEST(arg) Check((arg), __LINE__) |
|
183 #define TEST2(aValue, aExpected) Check(aValue, aExpected, __LINE__) |
|
184 |
|
185 /////////////////////////////////////////////////////////////////////////////////////// |
|
186 /////////////////////////////////////////////////////////////////////////////////////// |
|
187 //Global functions |
|
188 |
|
189 //Prepares the test directory. |
|
190 //TheFs.Connect() has to be called already. |
|
191 static void SetupTestDirectory() |
|
192 { |
|
193 TInt err = TheFs.MkDir(KTestDatabase); |
|
194 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
195 } |
|
196 |
|
197 //Leaves with info message printed out |
|
198 static void LeaveL(TInt aError, TInt aLine) |
|
199 { |
|
200 RDebug::Print(_L("*** Leave. Error: %d, Line: %d\r\n"), aError, aLine); |
|
201 User::Leave(aError); |
|
202 } |
|
203 |
|
204 //Leaves if aError < 0 with info message printed out |
|
205 static void LeaveIfErrorL(TInt aError, TInt aLine) |
|
206 { |
|
207 if(aError < KErrNone) |
|
208 { |
|
209 LeaveL(aError, aLine); |
|
210 } |
|
211 } |
|
212 |
|
213 //Use LEAVE() macro instead of User::Leave() and LEAVE_IF_ERROR() macro instead of |
|
214 //User::LeaveIfError(). They will print the line number, where the "leave" was called. |
|
215 #define LEAVE(aError) LeaveL(aError, __LINE__) |
|
216 #define LEAVE_IF_ERROR(aError) LeaveIfErrorL(aError, __LINE__) |
|
217 |
|
218 //Creates one or more large files with the total size near to the size of the available disk space. |
|
219 //The idea is to cause an "out of disk space" condition. |
|
220 static void FillLargeDataFileL(RFile& aFile, TInt aSize) |
|
221 { |
|
222 TInt err = KErrDiskFull; |
|
223 while(err == KErrDiskFull) |
|
224 { |
|
225 err = aFile.SetSize(aSize); |
|
226 aSize -= 100; |
|
227 if(aSize <= 0) |
|
228 { |
|
229 break; |
|
230 } |
|
231 } |
|
232 TEST(err == KErrNone || err == KErrDiskFull); |
|
233 } |
|
234 |
|
235 //Gets the available space of the tested drive. |
|
236 static TInt64 FreeDiskSpaceL() |
|
237 { |
|
238 TVolumeInfo volInfoBefore; |
|
239 LEAVE_IF_ERROR(TheFs.Volume(volInfoBefore, KTestDrive)); |
|
240 return volInfoBefore.iFree; |
|
241 } |
|
242 |
|
243 //Creates large data file with aSize size (in bytes). |
|
244 static void DoCreateLargeFileL(const TDesC& aPath, TInt aSize) |
|
245 { |
|
246 RFile file; |
|
247 CleanupClosePushL(file); |
|
248 LEAVE_IF_ERROR(file.Replace(TheFs, aPath, EFileRead | EFileWrite)); |
|
249 FillLargeDataFileL(file, aSize); |
|
250 LEAVE_IF_ERROR(file.Flush()); |
|
251 CleanupStack::PopAndDestroy(&file); |
|
252 } |
|
253 |
|
254 //Creates enough number of large data files to fill the available disk space. |
|
255 //It will change FilesCount global variable's value. |
|
256 static void CreateLargeFileL() |
|
257 { |
|
258 TInt fileNo = 0; |
|
259 const TInt KLargeFileSize = 1000000000; |
|
260 TInt64 diskSpace = FreeDiskSpaceL(); |
|
261 RDebug::Print(_L("CreateLargeFileL: free space before = %ld\n"), diskSpace); |
|
262 TBuf<KMaxFileName> filePath; |
|
263 const TInt64 KMinDiskSpace = 200; |
|
264 //Reserve almost all disk space, except a small amount - 200 bytes. |
|
265 while(diskSpace > KMinDiskSpace) |
|
266 { |
|
267 AssembleLargeFileName(KLargeFileName, fileNo++, filePath); |
|
268 TInt fileSize = KLargeFileSize; |
|
269 if(diskSpace < (TInt64)KLargeFileSize) |
|
270 { |
|
271 TInt64 lastFileSize = diskSpace - KMinDiskSpace; |
|
272 fileSize = I64LOW(lastFileSize); |
|
273 } |
|
274 DoCreateLargeFileL(filePath, fileSize); |
|
275 diskSpace = FreeDiskSpaceL(); |
|
276 RDebug::Print(_L("----CreateLargeFileL, step %d, free space = %ld\n"), fileNo, diskSpace); |
|
277 } |
|
278 diskSpace = FreeDiskSpaceL(); |
|
279 RDebug::Print(_L("CreateLargeFileL: free space after = %ld\n"), diskSpace); |
|
280 } |
|
281 |
|
282 //Reserves disk space for TheDbSession instance. |
|
283 //TheDbSession instance has to be connected already. |
|
284 static void ReserveDiskSpace() |
|
285 { |
|
286 TInt err = TheDbSession.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
287 TEST2(err, KErrNone); |
|
288 } |
|
289 |
|
290 //Frees already reserved disk space for TheDbSession instance. |
|
291 //TheDbSession instance has to be connected already. |
|
292 static void FreeReservedSpace() |
|
293 { |
|
294 TheDbSession.FreeReservedSpace(KTestDrive); |
|
295 } |
|
296 |
|
297 //Gets an access to the reserved disk space for TheDbSession instance. |
|
298 //TheDbSession instance has to be connected already. |
|
299 static void UnlockReservedSpace() |
|
300 { |
|
301 TInt err = TheDbSession.GetReserveAccess(KTestDrive); |
|
302 TEST2(err, KErrNone); |
|
303 } |
|
304 |
|
305 //Releases the access to the reserved disk space. |
|
306 //TheDbSession instance has to be connected already. |
|
307 static void LockReservedSpace() |
|
308 { |
|
309 (void)TheDbSession.ReleaseReserveAccess(KTestDrive); |
|
310 } |
|
311 |
|
312 //Creates the test DBMS session |
|
313 static void CreateTestDbSession() |
|
314 { |
|
315 TInt err = TheDbSession.Connect(); |
|
316 TEST2(err, KErrNone); |
|
317 } |
|
318 |
|
319 |
|
320 //Creates the test database |
|
321 //TheDbSession instance has to be connected already. |
|
322 //TheFs.Connect() has to be called already. |
|
323 static void CreateTestDatabase(RDbs& aDbs, RDbNamedDatabase& aDb) |
|
324 { |
|
325 //Create the test database. |
|
326 TInt err = aDb.Replace(TheFs, KTestDatabase); |
|
327 TEST2(err, KErrNone); |
|
328 TheDb.Close(); |
|
329 //Open it now using DBMS session (so, on DBMS server side), because we want to test |
|
330 //server side RFs sessions - handling "out of disk space" situations. |
|
331 err = aDb.Open(aDbs, KTestDatabase); |
|
332 TEST2(err, KErrNone); |
|
333 } |
|
334 |
|
335 //Creates a test table |
|
336 static void CreateTestTableL(RDbNamedDatabase& aDb) |
|
337 { |
|
338 CDbColSet* colSet = CDbColSet::NewLC(); |
|
339 for(const TColDef* colDef=KColDefs;colDef->iName;++colDef) |
|
340 { |
|
341 TDbCol col(TPtrC(colDef->iName), colDef->iType); |
|
342 col.iAttributes = colDef->iAttributes; |
|
343 colSet->AddL(col); |
|
344 } |
|
345 TEST2(aDb.CreateTable(KTestTableName, *colSet), KErrNone); |
|
346 CleanupStack::PopAndDestroy(colSet); |
|
347 } |
|
348 |
|
349 //Adds some data to the test table |
|
350 static void AddTestDataL(RDbNamedDatabase& aDb) |
|
351 { |
|
352 RDbTable tbl; |
|
353 CleanupClosePushL(tbl); |
|
354 TEST2(tbl.Open(aDb, KTestTableName, RDbRowSet::EUpdatable), KErrNone); |
|
355 for(TInt i=0;i<KTestRecordsCount;++i) |
|
356 { |
|
357 tbl.InsertL(); |
|
358 tbl.SetColL(2, _L8("1ABCDEFGHI2ABCDEFGHI3ABCDEFGHI4ABCDEFGHI5ABCDEFGHI6ABCDEFGHI7ABCDEFGHI8ABCDEFGHI9ABCDEFGHI0ABCDEFGHI")); |
|
359 tbl.PutL(); |
|
360 } |
|
361 TEST(tbl.CountL() == KTestRecordsCount); |
|
362 CleanupStack::PopAndDestroy(&tbl); |
|
363 } |
|
364 |
|
365 //Deletes some records from the test table using "delete" transaction. |
|
366 //Do not put TEST or TEST2 macro calls here (except for record count checks)! |
|
367 //The method must leave if some of the calls inside fail. |
|
368 static void DeleteRecordsL() |
|
369 { |
|
370 RDbTable tbl; |
|
371 CleanupClosePushL(tbl); |
|
372 LEAVE_IF_ERROR(tbl.Open(TheDb, KTestTableName, RDbRowSet::EUpdatable)); |
|
373 TEST(tbl.CountL() == KTestRecordsCount); |
|
374 TheDb.Begin(); |
|
375 tbl.FirstL(); |
|
376 for(TInt i=0;i<(KTestRecordsCount/2);++i) |
|
377 { |
|
378 tbl.DeleteL(); |
|
379 tbl.NextL(); |
|
380 } |
|
381 TInt err = TheDb.Commit(); |
|
382 if(err != KErrNone) |
|
383 { |
|
384 TheDb.Rollback(); |
|
385 LEAVE(err); |
|
386 } |
|
387 TEST(tbl.CountL() == (KTestRecordsCount / 2)); |
|
388 CleanupStack::PopAndDestroy(&tbl); |
|
389 } |
|
390 |
|
391 /** |
|
392 The function simply calls RDbs::ReserveDriveSpace(), RDbs::GetReserveAccess(), |
|
393 RDbs::ReleaseReserveAccess() methods and checks the return values. |
|
394 It might be usefull for debugging in case if something gets wrong. |
|
395 |
|
396 @SYMTestCaseID SYSLIB-DBMS-CT-0647 |
|
397 @SYMTestCaseDesc Tests for attempting to reserve disk space |
|
398 @SYMTestPriority Medium |
|
399 @SYMTestActions Calls up RDbs::ReserveDriveSpace(), RDbs::GetReserveAccess(), |
|
400 RDbs::ReleaseReserveAccess() methods and checks the return values. |
|
401 @SYMTestExpectedResults Test must not fail |
|
402 @SYMREQ REQ0000 |
|
403 */ |
|
404 static void SimpleCallsL() |
|
405 { |
|
406 RDbs dbs; |
|
407 CleanupClosePushL(dbs); |
|
408 LEAVE_IF_ERROR(dbs.Connect()); |
|
409 |
|
410 //Reserve disk space |
|
411 TInt err = dbs.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
412 TEST2(err, KErrNone); |
|
413 |
|
414 //An attempt to re-reserve it |
|
415 err = dbs.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
416 TEST2(err, KErrInUse); |
|
417 |
|
418 //Get an access to the reserved disk space |
|
419 err = dbs.GetReserveAccess(KTestDrive); |
|
420 TEST2(err, KErrNone); |
|
421 |
|
422 //An attempt to get an access to the reserved space twice. |
|
423 err = dbs.GetReserveAccess(KTestDrive); |
|
424 TEST2(err, KErrInUse); |
|
425 |
|
426 //This call must fail, because it tries to get an access to the reserved space of |
|
427 //not the same drive, for which ReserveDriveSpace() was called. |
|
428 err = dbs.GetReserveAccess(KTestDrive + 1); |
|
429 TEST(err != KErrNone); |
|
430 |
|
431 (void)dbs.ReleaseReserveAccess(KTestDrive); |
|
432 |
|
433 //An attempt to release the reserved space twice. This call will panic in debug mode. |
|
434 //(void)dbs.ReleaseReserveAccess(KTestDrive); |
|
435 |
|
436 //Cancel reserving an additional disk space |
|
437 dbs.FreeReservedSpace(KTestDrive); |
|
438 |
|
439 //Cancel reserving an additional disk space twice |
|
440 //This call will panic in debug mode. |
|
441 //dbs.FreeReservedSpace(KTestDrive); |
|
442 |
|
443 CleanupStack::PopAndDestroy(&dbs); |
|
444 } |
|
445 |
|
446 /** |
|
447 @SYMTestCaseID SYSLIB-DBMS-CT-0648 |
|
448 @SYMTestCaseDesc Transactions test |
|
449 Simulating an "out of disk space" situation |
|
450 @SYMTestPriority Medium |
|
451 @SYMTestActions Transaction test under "out of disk space" circumstances |
|
452 while reserving disk space. |
|
453 @SYMTestExpectedResults Test must not fail |
|
454 @SYMREQ REQ0000 |
|
455 */ |
|
456 static void TransactionTestL() |
|
457 { |
|
458 TVolumeIOParamInfo volIoPrm; |
|
459 TInt err = TheFs.VolumeIOParam(KTestDrive, volIoPrm); |
|
460 TEST2(err, KErrNone); |
|
461 RDebug::Print(_L("--Drive %d. BlockSize=%d, ClusterSize=%d, RecReadBufSize=%d, RecWriteBufSize=%d\r\n"), KTestDrive, volIoPrm.iBlockSize, volIoPrm.iClusterSize, volIoPrm.iRecReadBufSize, volIoPrm.iRecWriteBufSize); |
|
462 ///////////////////////////////////////////////////////// |
|
463 CreateTestDbSession(); |
|
464 //Rserve disk space |
|
465 ReserveDiskSpace(); |
|
466 //Create test database and table. Add some test data to them. |
|
467 CreateTestDatabase(TheDbSession, TheDb); |
|
468 CreateTestTableL(TheDb); |
|
469 AddTestDataL(TheDb); |
|
470 RDebug::Print(_L("--Simulate an \"out of disk space\" situation with creating a very large data file, which occupies almost the all the available disk space.\r\n")); |
|
471 CreateLargeFileL(); |
|
472 RDebug::Print(_L("--Attempt to delete test data records. The transaction must fail, because of \"out of disk space\".\r\n")); |
|
473 TInt64 diskSpace = FreeDiskSpaceL(); |
|
474 RDebug::Print(_L("--Attempt to delete test data records. Free disk space = %ld\n"), diskSpace); |
|
475 TRAP(err, DeleteRecordsL()); |
|
476 RDebug::Print(_L("--DeleteRecordsL() returned %d error\r\n"), err); |
|
477 TEST(err != KErrNone); |
|
478 RDebug::Print(_L("--The attempt failed with err=%d. Get an access to the reserved disk space.\r\n"), err); |
|
479 UnlockReservedSpace(); |
|
480 RDebug::Print(_L("--Try again with getting an access to the reserved disk space.\n")); |
|
481 diskSpace = FreeDiskSpaceL(); |
|
482 RDebug::Print(_L("After GetReserveAccess(), free disk space = %ld\r\n"), diskSpace); |
|
483 DeleteRecordsL(); |
|
484 RDebug::Print(_L("--\"Delete\" transaction was completed successfully.\n")); |
|
485 //Free the resources, used in the test |
|
486 DeleteLargeDataFiles(); |
|
487 LockReservedSpace(); |
|
488 FreeReservedSpace(); |
|
489 } |
|
490 |
|
491 /** |
|
492 @SYMTestCaseID SYSLIB-DBMS-CT-0649 |
|
493 @SYMTestCaseDesc OOD tests with two DBMS sessions. |
|
494 @SYMTestPriority Medium |
|
495 @SYMTestActions The test actually checks that the DBMS server is in a stable state, when there is more |
|
496 than one RDbs session and a shared database is accessed. |
|
497 The first check is that the shared database can be accessed without any problem through |
|
498 any of the sessions: first or second. |
|
499 Then the second session is closed and the shared database is accessed |
|
500 through the first DBMS session - the operations should not fail. |
|
501 @SYMTestExpectedResults Test must not fail |
|
502 @SYMREQ REQ0000 |
|
503 */ |
|
504 static void TwoSessTestL() |
|
505 { |
|
506 //Create session1, open a shared database, open a shared table through session 1 |
|
507 RDbs dbSess1; |
|
508 CleanupClosePushL(dbSess1); |
|
509 LEAVE_IF_ERROR(dbSess1.Connect()); |
|
510 |
|
511 RDbNamedDatabase db1; |
|
512 CleanupClosePushL(db1); |
|
513 TInt err = db1.Open(dbSess1, KTestDatabase); |
|
514 TEST2(err, KErrNone); |
|
515 |
|
516 RDbTable tbl1; |
|
517 CleanupClosePushL(tbl1); |
|
518 TEST2(tbl1.Open(db1, KTestTableName, RDbRowSet::EUpdatable), KErrNone); |
|
519 |
|
520 //Create session2, open shared database, open shared table through session 2 |
|
521 RDbs dbSess2; |
|
522 CleanupClosePushL(dbSess2); |
|
523 LEAVE_IF_ERROR(dbSess2.Connect()); |
|
524 |
|
525 RDbNamedDatabase db2; |
|
526 CleanupClosePushL(db2); |
|
527 err = db2.Open(dbSess2, KTestDatabase); |
|
528 TEST2(err, KErrNone); |
|
529 |
|
530 RDbTable tbl2; |
|
531 CleanupClosePushL(tbl2); |
|
532 TEST2(tbl2.Open(db2, KTestTableName, RDbRowSet::EUpdatable), KErrNone); |
|
533 |
|
534 //Here we have two sessions and two instances of RDbNamedDatabase type, which |
|
535 //operate on a shared database. Insert a record through the sessions. |
|
536 |
|
537 tbl1.InsertL(); |
|
538 tbl1.SetColL(2, _L8("--------------------------1----------------------------------------")); |
|
539 tbl1.PutL(); |
|
540 |
|
541 tbl2.InsertL(); |
|
542 tbl2.SetColL(2, _L8("========================2======================================")); |
|
543 tbl2.PutL(); |
|
544 |
|
545 //Close the second session. It should be able to access the shared database via the |
|
546 //first session. |
|
547 |
|
548 CleanupStack::PopAndDestroy(&tbl2); |
|
549 CleanupStack::PopAndDestroy(&db2); |
|
550 CleanupStack::PopAndDestroy(&dbSess2); |
|
551 |
|
552 //Try to access again the shared database. |
|
553 tbl1.InsertL(); |
|
554 tbl1.SetColL(2, _L8("+++++++++++++++++++++++++++++++++++3++++++++++++++++++++++++++++++++++++++++++")); |
|
555 tbl1.PutL(); |
|
556 |
|
557 CleanupStack::PopAndDestroy(&tbl1); |
|
558 CleanupStack::PopAndDestroy(&db1); |
|
559 CleanupStack::PopAndDestroy(&dbSess1); |
|
560 } |
|
561 |
|
562 /** |
|
563 @SYMTestCaseID SYSLIB-DBMS-CT-0650 |
|
564 @SYMTestCaseDesc OOD tests with more than one DBMS session. |
|
565 @SYMTestPriority Medium |
|
566 @SYMTestActions The test calls ReserveDriveSpace/GetReserveAccess/ReleaseReserveAccess in a different |
|
567 combinations on four DBMS sessions. The test should not fail or panic. |
|
568 @SYMTestExpectedResults Test must not fail |
|
569 @SYMREQ REQ0000 |
|
570 */ |
|
571 static void TwoSessTest2L() |
|
572 { |
|
573 //Create session1 |
|
574 RDbs dbSess1; |
|
575 CleanupClosePushL(dbSess1); |
|
576 LEAVE_IF_ERROR(dbSess1.Connect()); |
|
577 |
|
578 //Create session2 |
|
579 RDbs dbSess2; |
|
580 CleanupClosePushL(dbSess2); |
|
581 LEAVE_IF_ERROR(dbSess2.Connect()); |
|
582 |
|
583 //Play with "ReserveDriveSpace" on both sessions |
|
584 TInt err = dbSess1.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
585 TEST2(err, KErrNone); |
|
586 err = dbSess2.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
587 TEST2(err, KErrNone); |
|
588 dbSess2.FreeReservedSpace(KTestDrive); |
|
589 err = dbSess2.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
590 TEST2(err, KErrNone); |
|
591 |
|
592 //Get an access to the reserved space through session 2 |
|
593 err = dbSess2.GetReserveAccess(KTestDrive); |
|
594 TEST2(err, KErrNone); |
|
595 //Free/re-reserve disk space for session 1. |
|
596 dbSess1.FreeReservedSpace(KTestDrive); |
|
597 err = dbSess1.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
598 TEST2(err, KErrNone); |
|
599 |
|
600 //Create session4 |
|
601 RDbs dbSess4; |
|
602 CleanupClosePushL(dbSess4); |
|
603 LEAVE_IF_ERROR(dbSess4.Connect()); |
|
604 |
|
605 //Try to reserve space for session 4. |
|
606 err = dbSess4.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
607 TEST2(err, KErrNone); |
|
608 |
|
609 //Create session3 |
|
610 RDbs dbSess3; |
|
611 CleanupClosePushL(dbSess3); |
|
612 LEAVE_IF_ERROR(dbSess3.Connect()); |
|
613 //Try to reserve space for session 3. |
|
614 err = dbSess3.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
615 TEST2(err, KErrNone); |
|
616 |
|
617 //Release and free session 2 access to the reserved space. |
|
618 (void)dbSess2.ReleaseReserveAccess(KTestDrive); |
|
619 dbSess2.FreeReservedSpace(KTestDrive); |
|
620 |
|
621 dbSess3.FreeReservedSpace(KTestDrive); |
|
622 CleanupStack::PopAndDestroy(&dbSess3); |
|
623 |
|
624 dbSess4.FreeReservedSpace(KTestDrive); |
|
625 CleanupStack::PopAndDestroy(&dbSess4); |
|
626 |
|
627 //Get an access to the reserved space through session 2. |
|
628 //But it was freed, so the call will fail. |
|
629 err = dbSess2.GetReserveAccess(KTestDrive); |
|
630 TEST(err != KErrNone); |
|
631 |
|
632 //Free/re-reserve disk space for session 1. |
|
633 dbSess1.FreeReservedSpace(KTestDrive); |
|
634 err = dbSess1.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
635 TEST2(err, KErrNone); |
|
636 |
|
637 //Grant/release the access to the reserved space for session 1. |
|
638 err = dbSess1.GetReserveAccess(KTestDrive); |
|
639 TEST2(err, KErrNone); |
|
640 (void)dbSess1.ReleaseReserveAccess(KTestDrive); |
|
641 |
|
642 //Grant an access to the reserved space for session 2. |
|
643 //The call will fail because there is no reserved disk space for session 2. |
|
644 err = dbSess2.GetReserveAccess(KTestDrive); |
|
645 TEST(err != KErrNone); |
|
646 |
|
647 //Free the reserved space - session 1 |
|
648 dbSess1.FreeReservedSpace(KTestDrive); |
|
649 |
|
650 CleanupStack::PopAndDestroy(&dbSess2); |
|
651 CleanupStack::PopAndDestroy(&dbSess1); |
|
652 } |
|
653 |
|
654 /** |
|
655 @SYMTestCaseID SYSLIB-DBMS-CT-0651 |
|
656 @SYMTestCaseDesc Out of memory tests |
|
657 @SYMTestPriority Medium |
|
658 @SYMTestActions Checks RDbs::ReserveDriveSpace() behaviour under OOM circumstances |
|
659 @SYMTestExpectedResults Test must not fail |
|
660 @SYMREQ REQ0000 |
|
661 */ |
|
662 static void OOMTest1() |
|
663 { |
|
664 RDbs dbs; |
|
665 TEST2(dbs.Connect(), KErrNone); |
|
666 dbs.ResourceMark(); |
|
667 for(TInt count=1;;++count) |
|
668 { |
|
669 RDebug::Print(_L("OOMTest1. Count=%d\n"), count); |
|
670 dbs.SetHeapFailure(RHeap::EFailNext, count); |
|
671 |
|
672 TInt ret = dbs.ReserveDriveSpace(KTestDrive, KReservedSpaceSize); |
|
673 |
|
674 if(ret == KErrNoMemory) |
|
675 { |
|
676 dbs.ResourceCheck(); |
|
677 } |
|
678 else if(ret == KErrNone) |
|
679 { |
|
680 dbs.FreeReservedSpace(KTestDrive); |
|
681 break; |
|
682 } |
|
683 else |
|
684 { |
|
685 TEST2(ret, KErrNone); |
|
686 } |
|
687 } |
|
688 |
|
689 dbs.SetHeapFailure(RHeap::ENone, 0); |
|
690 dbs.Close(); |
|
691 } |
|
692 |
|
693 /** |
|
694 @SYMTestCaseID SYSLIB-DBMS-CT-0652 |
|
695 @SYMTestCaseDesc Out of memory tests |
|
696 @SYMTestPriority Medium |
|
697 @SYMTestActions Checks RDbs::GetReserveAccess() behaviour under OOM circumstances |
|
698 @SYMTestExpectedResults Test must not fail |
|
699 @SYMREQ REQ0000 |
|
700 */ |
|
701 static void OOMTest2() |
|
702 { |
|
703 RDbs dbs; |
|
704 TEST2(dbs.Connect(), KErrNone); |
|
705 TEST2(dbs.ReserveDriveSpace(KTestDrive, KReservedSpaceSize), KErrNone); |
|
706 dbs.ResourceMark(); |
|
707 for(TInt count=1;;++count) |
|
708 { |
|
709 RDebug::Print(_L("OOMTest2. Count=%d\n"), count); |
|
710 dbs.SetHeapFailure(RHeap::EFailNext, count); |
|
711 |
|
712 TInt ret = dbs.GetReserveAccess(KTestDrive); |
|
713 |
|
714 if(ret == KErrNoMemory) |
|
715 { |
|
716 dbs.ResourceCheck(); |
|
717 } |
|
718 else if(ret == KErrNone) |
|
719 { |
|
720 (void)dbs.ReleaseReserveAccess(KTestDrive); |
|
721 break; |
|
722 } |
|
723 else |
|
724 { |
|
725 TEST2(ret, KErrNone); |
|
726 } |
|
727 } |
|
728 |
|
729 dbs.FreeReservedSpace(KTestDrive); |
|
730 dbs.SetHeapFailure(RHeap::ENone, 0); |
|
731 dbs.Close(); |
|
732 } |
|
733 |
|
734 |
|
735 //Used in DEF057265(). |
|
736 static TInt ThreadFunc(void*) |
|
737 { |
|
738 User::SetJustInTime(EFalse); // disable debugger panic handling |
|
739 //Create DBMS session. Reserve drive space. |
|
740 RDbs dbs; |
|
741 TEST2(dbs.Connect(), KErrNone); |
|
742 TEST2(dbs.ReserveDriveSpace(KTestDrive, KReservedSpaceSize), KErrNone); |
|
743 //Panic thread. See DBMS server behaviour - will it panic or not? |
|
744 //If DBMS server panics in _DEBUG mode - DEF057265 is not properly fixed. |
|
745 User::Panic(_L("Simulate DBMS client failuer"), 0); |
|
746 return KErrNone; |
|
747 } |
|
748 |
|
749 //DEF057265 - Panics when uninstalling a java midlet while it is running. |
|
750 //The test will run one thread. Inside the thread's function the test will create |
|
751 //DBMS session and reserve some disk space. Then the test will panic the thread |
|
752 //(without freeing the reserved disk space). |
|
753 //If DBMS server panics in _DEBUG mode - the defect is not fixed. |
|
754 void DEF057265() |
|
755 { |
|
756 _LIT(KSessThreadName,"SessThrd"); |
|
757 RThread sessThread; |
|
758 TEST2(sessThread.Create(KSessThreadName, &ThreadFunc, 0x2000, 0, 0), KErrNone); |
|
759 |
|
760 TRequestStatus sessThreadStatus; |
|
761 sessThread.Logon(sessThreadStatus); |
|
762 TEST2(sessThreadStatus.Int(), KRequestPending); |
|
763 |
|
764 sessThread.Resume(); |
|
765 User::WaitForRequest(sessThreadStatus); |
|
766 TEST2(sessThread.ExitType(), EExitPanic); |
|
767 |
|
768 User::SetJustInTime(EFalse); // disable debugger panic handling |
|
769 sessThread.Close();//This Close() operation will force DBMS server to close |
|
770 //created in ThreadFunc() DBMS session. |
|
771 } |
|
772 |
|
773 /////////////////////////////////////////////////////////////////////////////////////// |
|
774 /////////////////////////////////////////////////////////////////////////////////////// |
|
775 //The main test function. |
|
776 //Call your new test functions from here |
|
777 static void RunTestsL() |
|
778 { |
|
779 TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0647 RDbs OOD methods calls ")); |
|
780 SimpleCallsL(); |
|
781 |
|
782 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0648 Transaction test with reserving disk space ")); |
|
783 TransactionTestL(); |
|
784 |
|
785 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0649 Two DBMS sessions test ")); |
|
786 TwoSessTestL(); |
|
787 |
|
788 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0650 Two DBMS sessions test-2 ")); |
|
789 TwoSessTest2L(); |
|
790 |
|
791 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0651 DBMS OOD - OOM test 1 ")); |
|
792 OOMTest1(); |
|
793 |
|
794 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-DBMS-CT-0652 DBMS OOD - OOM test 2 ")); |
|
795 OOMTest2(); |
|
796 |
|
797 TheTest.Next(_L("DEF057265 Panics when uninstalling a java midlet while it is running")); |
|
798 DEF057265(); |
|
799 |
|
800 //Add tests here! |
|
801 } |
|
802 |
|
803 TInt E32Main() |
|
804 { |
|
805 TheTest.Title(); |
|
806 |
|
807 __UHEAP_MARK; |
|
808 |
|
809 CTrapCleanup* trapCleanup = CTrapCleanup::New(); |
|
810 TEST(trapCleanup != NULL); |
|
811 |
|
812 DeleteLargeDataFiles(); |
|
813 |
|
814 TInt err = TheFs.Connect(); |
|
815 TEST2(err, KErrNone); |
|
816 SetupTestDirectory(); |
|
817 |
|
818 TRAP(err, RunTestsL()); |
|
819 TheDb.Close(); |
|
820 TheDbSession.Close(); |
|
821 TheFs.Close(); |
|
822 TEST2(err, KErrNone); |
|
823 |
|
824 DeleteDataFiles();//delete the data files used by this test |
|
825 |
|
826 TheTest.End(); |
|
827 TheTest.Close(); |
|
828 |
|
829 delete trapCleanup; |
|
830 |
|
831 __UHEAP_MARKEND; |
|
832 |
|
833 return 0; |
|
834 } |
|
835 |
|
836 |