--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/sql/TEST/t_sqlfilebuf64.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,1058 @@
+// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+#include <e32test.h>
+
+#ifdef _SQLPROFILER
+
+#include <bautils.h>
+#include "FileBuf64.h"
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+TBool TheOsCallTimeDetailedProfileEnabled = ETrue;//Needed because the RFileBuf64 source is included directly into this test
+ //nd the sql profiler is enabled (_SQLPROFILER is defined in the MMP file)
+
+static RTest TheTest(_L("t_sqlfilebuf64 test"));
+static RFs TheFs;
+
+_LIT(KTestDir, "c:\\test\\");
+_LIT(KTestFile, "c:\\test\\t_sqlfilebuf64.bin");
+_LIT(KTestFile2, "\\test\\t_sqlfilebuf64_2.bin");
+
+static TBuf8<1024> TheBuf;
+static TFileName TheDbName;
+
+static TInt TheProcessHandleCount = 0;
+static TInt TheThreadHandleCount = 0;
+static TInt TheAllocatedCellsCount = 0;
+
+#ifdef _DEBUG
+static const TInt KBurstRate = 100;
+#endif
+
+enum TOomTestType
+ {
+ EOomCreateTest,
+ EOomOpenTest,
+ EOomTempTest
+ };
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void DeleteTestFiles()
+ {
+ if(TheDbName.Length() > 0)
+ {
+ (void)TheFs.Delete(TheDbName);
+ }
+ (void)TheFs.Delete(KTestFile);
+ }
+
+void TestEnvDestroy()
+ {
+ DeleteTestFiles();
+ TheFs.Close();
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
+//Test macros and functions
+void Check1(TInt aValue, TInt aLine)
+ {
+ if(!aValue)
+ {
+ TestEnvDestroy();
+ RDebug::Print(_L("*** Line %d\r\n"), aLine);
+ TheTest(EFalse, aLine);
+ }
+ }
+void Check2(TInt aValue, TInt aExpected, TInt aLine)
+ {
+ if(aValue != aExpected)
+ {
+ TestEnvDestroy();
+ RDebug::Print(_L("*** Line %d, Expected result: %d, got: %d\r\n"), aLine, aExpected, aValue);
+ TheTest(EFalse, aLine);
+ }
+ }
+#define TEST(arg) ::Check1((arg), __LINE__)
+#define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__)
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void TestEnvInit()
+ {
+ TInt err = TheFs.Connect();
+ TEST2(err, KErrNone);
+
+ err = TheFs.MkDir(KTestDir);
+ TEST(err == KErrNone || err == KErrAlreadyExists);
+ }
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+static void MarkHandles()
+ {
+ RThread().HandleCount(TheProcessHandleCount, TheThreadHandleCount);
+ }
+
+static void MarkAllocatedCells()
+ {
+ TheAllocatedCellsCount = User::CountAllocCells();
+ }
+
+static void CheckAllocatedCells()
+ {
+ TInt allocatedCellsCount = User::CountAllocCells();
+ TEST2(allocatedCellsCount, TheAllocatedCellsCount);
+ }
+
+static void CheckHandles()
+ {
+ TInt endProcessHandleCount;
+ TInt endThreadHandleCount;
+
+ RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);
+
+ TEST2(TheProcessHandleCount, endProcessHandleCount);
+ TEST2(TheThreadHandleCount, endThreadHandleCount);
+ }
+
+static void VerifyFileContent(const TDesC8& aPattern)
+ {
+ TheBuf.Zero();
+
+ RFile64 file;
+ TInt err = file.Open(TheFs, KTestFile, EFileShareReadersOrWriters);
+ TEST2(err, KErrNone);
+
+ TInt64 fsize;
+ err = file.Size(fsize);
+ TEST2(err, KErrNone);
+ TEST2((TInt)fsize, aPattern.Length());
+
+ err = file.Read(TheBuf, aPattern.Length());
+ TEST2(err, KErrNone);
+
+ file.Close();
+
+ err = TheBuf.Compare(aPattern);
+ TEST2(err, 0);
+ }
+
+static void VerifyFileContent(const TDesC8& aPattern, TInt64 aFilePos)
+ {
+ __ASSERT_DEBUG(aFilePos >= 0, User::Invariant());
+
+ TheBuf.Zero();
+
+ RFile64 file;
+ TInt err = file.Open(TheFs, KTestFile, EFileShareReadersOrWriters);
+ TEST2(err, KErrNone);
+
+ err = file.Read(aFilePos, TheBuf, aPattern.Length());
+ TEST2(err, KErrNone);
+
+ file.Close();
+
+ err = TheBuf.Compare(aPattern);
+ TEST2(err, 0);
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4132
+@SYMTestCaseDesc RFileBuf64 write test 1.
+ The test performs file write operations using RFileBuf64 class.
+ The write positions are inside the buffer or right at the end of the buffer.
+ The purpose of the test: to verify the logic of RFileBuf64::Write().
+@SYMTestActions RFileBuf64 write test 1.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void WriteTest1()
+ {
+ RFileBuf64 fbuf(1024);
+ TInt err = fbuf.Create(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //Zero write request
+ err = fbuf.Write(0, _L8(""));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+
+ //First write operation. After the operation the file buffer must countain 10 bytes.
+ err = fbuf.Write(0, _L8("A123456789"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ //Second write operation. The offset is at the middle of the buffer. Data length: 10;
+ err = fbuf.Write(5, _L8("ZZZZZEEEEE"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+
+ //Third write operation. The offset is at the end of the buffer. Data length: 5;
+ err = fbuf.Write(15, _L8("CCCCC"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+
+ err = fbuf.Flush();
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 1);
+ TEST2(fbuf.iFileFlushCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 20);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ fbuf.Close();
+
+ VerifyFileContent(_L8("A1234ZZZZZEEEEECCCCC"));
+
+ (void)TheFs.Delete(KTestFile);
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4133
+@SYMTestCaseDesc RFileBuf64 write test 2.
+ The test performs file write operations using RFileBuf64 class.
+ The write positions are beyound the end of the file but within the buffer capacity.
+ The purpose of the test: to verify the logic of RFileBuf64::Write().
+@SYMTestActions RFileBuf64 write test 2.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void WriteTest2()
+ {
+ RFileBuf64 fbuf(1024);
+ TInt err = fbuf.Create(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //First write operation. After the operation the file buffer must countain 10 bytes.
+ err = fbuf.Write(0, _L8("A123456789"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ //Second write operation. After the operation the file buffer must countain 10 + 10 zeros + 10 bytes.
+ err = fbuf.Write(20, _L8("FFGGHHJJKK"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ err = fbuf.Flush();
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 1);
+ TEST2(fbuf.iFileFlushCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 30);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ fbuf.Close();
+
+ TBuf8<30> pattern;
+ pattern.Append(_L8("A123456789"));
+ pattern.AppendFill(TChar(0), 10);
+ pattern.Append(_L8("FFGGHHJJKK"));
+ VerifyFileContent(pattern);
+
+ (void)TheFs.Delete(KTestFile);
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4134
+@SYMTestCaseDesc RFileBuf64 write test 3.
+ The test performs file write operations using RFileBuf64 class.
+ The write position is before the start of the buffer but there is room for move.
+ The purpose of the test: to verify the logic of RFileBuf64::Write().
+@SYMTestActions RFileBuf64 write test 3.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void WriteTest3()
+ {
+ //Iteration 1: The file length is 0, the first operation is "write beyond the end"
+ //Iteration 2: The file length is 30, the first write operation is within the file.
+ for(TInt i=0;i<2;++i)
+ {
+ RFileBuf64 fbuf(1024);
+ TInt err = i == 0 ? fbuf.Create(TheFs, KTestFile, EFileWrite) : fbuf.Open(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //First write operation. The offset is not 0. Data length: 10;
+ err = fbuf.Write(20, _L8("A123456789"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ //Second write operation. The offset is 0. Data length: 20;
+ err = fbuf.Write(0, _L8("AASSDDFFRR**********"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ err = fbuf.Flush();
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 1);
+ TEST2(fbuf.iFileFlushCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 30);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ fbuf.Close();
+
+ VerifyFileContent(_L8("AASSDDFFRR**********A123456789"));
+ }
+ (void)TheFs.Delete(KTestFile);
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4135
+@SYMTestCaseDesc RFileBuf64 write test 4.
+ The test performs file write operations using RFileBuf64 class and verifies that
+ that the pending write data will be stored in the file when the buffer is closed.
+ The purpose of the test: to verify the logic of RFileBuf64::Write().
+@SYMTestActions RFileBuf64 write test 4.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void WriteTest4()
+ {
+ RFileBuf64 fbuf(1024);
+ TInt err = fbuf.Create(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ // Data length: 10;
+ err = fbuf.Write(0, _L8("A123456789"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ // Data length: 0;
+ err = fbuf.Write(10, _L8(""));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ fbuf.Close();
+
+ VerifyFileContent(_L8("A123456789"));
+
+ (void)TheFs.Delete(KTestFile);
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4136
+@SYMTestCaseDesc RFileBuf64 write test 5.
+ The test performs file write operations using RFileBuf64 class.
+ The data is written before the start of the file buffer and is too big to fit in the buffer.
+ The purpose of the test: to verify the logic of RFileBuf64::Write().
+@SYMTestActions RFileBuf64 write test 5.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void WriteTest5()
+ {
+ RFileBuf64 fbuf(20);
+ TInt err = fbuf.Create(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //First write operation. The offset is not 0. Data length: 10;
+ err = fbuf.Write(10, _L8("A123456789"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ //Second write operation. The offset is 0. Data length: 12;
+ err = fbuf.Write(0, _L8("ZZXXCCVVBBNN"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 20);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ err = fbuf.Flush();
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 2);
+ TEST2(fbuf.iFileFlushCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 20 + 12);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ fbuf.Close();
+
+ VerifyFileContent(_L8("ZZXXCCVVBBNN23456789"));
+
+ (void)TheFs.Delete(KTestFile);
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4137
+@SYMTestCaseDesc RFileBuf64 write test 6.
+ The test performs file write operations using RFileBuf64 class.
+ The data is written before the start of the file buffer and is too big to fit in the buffer.
+ The purpose of the test: to verify the logic of RFileBuf64::Write().
+@SYMTestActions RFileBuf64 write test 6.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void WriteTest6()
+ {
+ RFileBuf64 fbuf(20);
+ TInt err = fbuf.Create(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+
+ err = fbuf.Write(0, _L8("A123456789B123456789C123456789"));
+ TEST2(err, KErrNone);
+ err = fbuf.Flush();
+ TEST2(err, KErrNone);
+ fbuf.Close();
+ VerifyFileContent(_L8("A123456789B123456789C123456789"));
+
+ err = fbuf.Open(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //First write operation. The offset is not 0. Data length: 10;
+ err = fbuf.Write(15, _L8("OOOOOOOOOO"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ //Second write operation. The offset is 0. Data length: 15;
+ err = fbuf.Write(0, _L8("TTTTTTTTTTTTTTT"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 10);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ err = fbuf.Flush();
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileWriteCount, 2);
+ TEST2(fbuf.iFileFlushCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 15 + 10);
+ TEST2(fbuf.iFileSizeCount, 1);
+
+ fbuf.Close();
+
+ VerifyFileContent(_L8("TTTTTTTTTTTTTTTOOOOOOOOOO56789"));
+
+ (void)TheFs.Delete(KTestFile);
+ }
+
+void PrepareReadTest()
+ {
+ RFile64 file;
+ TInt err = file.Create(TheFs, KTestFile, EFileWrite);
+ TEST2(err, KErrNone);
+ err = file.Write(_L8("A123456789ZZZZZZZZZZB-B-B-B-B-Y*Y*Y*Y*Y*"));
+ TEST2(err, KErrNone);
+ err = file.Flush();
+ TEST2(err, KErrNone);
+ file.Close();
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4138
+@SYMTestCaseDesc RFileBuf64 read test 1.
+ The test performs file read operations using RFileBuf64 class.
+ Tested "read" operations:
+ - Zero max length request;
+ - Too big read request;
+ - Read beyond the end of the file;
+ The purpose of the test: to verify the logic of RFileBuf64::Read().
+@SYMTestActions RFileBuf64 read test 1.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void ReadTest1()
+ {
+ const TInt KBufMaxSize = 20;// This is half the file size
+ RFileBuf64 fbuf(KBufMaxSize);
+ TInt err = fbuf.Open(TheFs, KTestFile, EFileWrite | EFileRead | EFileShareReadersOrWriters);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //Zero max length request
+ HBufC8* buf1 = HBufC8::New(0);
+ TEST(buf1 != NULL);
+ TPtr8 ptr1 = buf1->Des();
+ err = fbuf.Read(0, ptr1);
+ TEST2(err, KErrNone);
+ delete buf1;
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+
+ //Too big request
+ TBuf8<KBufMaxSize * 2> buf2;
+ err = fbuf.Read(0, buf2);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, (KBufMaxSize * 2));
+ TEST2(fbuf.iFileSizeCount, 1);
+ VerifyFileContent(buf2);
+
+ //Read beyond the end of the file
+ err = fbuf.Read(2000, buf2);
+ TEST2(err, KErrNone);
+ TEST2(buf2.Length(), 0);
+
+ fbuf.Close();
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4139
+@SYMTestCaseDesc RFileBuf64 read test 2.
+ The test performs file read operations using RFileBuf64 class.
+ Tested operations:
+ - Non-buffered reads;
+ - Buffered reads;
+ The purpose of the test: to verify the logic of RFileBuf64::Read().
+@SYMTestActions RFileBuf64 read test 2.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void ReadTest2()
+ {
+ RFileBuf64 fbuf(1024);
+ TInt err = fbuf.Open(TheFs, KTestFile, EFileWrite | EFileRead | EFileShareReadersOrWriters);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //1. Read bytes [0..20]
+ TBuf8<20> buf1;
+ err = fbuf.Read(0, buf1);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, 20);
+ TEST2(fbuf.iFileSizeCount, 1);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf1, 0);
+
+ //2. Read again, bytes [10..20]. They are not buffered.
+ TBuf8<10> buf2;
+ err = fbuf.Read(10, buf2);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, 10);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf2, 10);
+
+ //3. Read again, bytes [20..30]. They are not buffered. But the file buffer will be populated,
+ // because the file read position matches the guessed file read position from step 2.
+ err = fbuf.Read(20, buf2);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, (10 * 2));
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf2, 20);
+
+ //4. Read again, bytes [25..35]. This is a buffered read operation.
+ err = fbuf.Read(25, buf2);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf2, 25);
+
+ //5. Read again, bytes [15..25]. This is a non buffered read operation.
+ err = fbuf.Read(15, buf2);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, 10);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf2, 15);
+
+ //6. Read again, bytes [25..35]. This is a buffered read operation. The buffer from step 3 is still there.
+ err = fbuf.Read(25, buf2);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf2, 25);
+
+ //7. Read again, bytes [35..45] - beyond the end of the file.
+ // This is a buffered read operation. The buffer from step 3 is still there.
+ err = fbuf.Read(35, buf2);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+ TEST2(buf2.Size(), 5);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf2, 35);
+
+ fbuf.Close();
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4140
+@SYMTestCaseDesc RFileBuf64 read test 3.
+ The test performs file read operations using RFileBuf64 class.
+ Tested operations:
+ - Non-buffered reads;
+ - Buffered reads;
+ - Part- buffered reads;
+ The purpose of the test: to verify the logic of RFileBuf64::Read().
+@SYMTestActions RFileBuf64 read test 3.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void ReadTest3()
+ {
+ RFileBuf64 fbuf(1024);
+ TInt err = fbuf.Open(TheFs, KTestFile, EFileWrite | EFileRead | EFileShareReadersOrWriters);
+ TEST2(err, KErrNone);
+ fbuf.ProfilerReset();
+
+ //1. Read bytes [0..10]. Non buffered.
+ TBuf8<10> buf1;
+ err = fbuf.Read(0, buf1);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, 10);
+ TEST2(fbuf.iFileSizeCount, 1);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf1, 0);
+
+ //2. Read bytes [10..20]. Non buffered. But the file buffer is populated, bytes [10..40].
+ err = fbuf.Read(10, buf1);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, 30);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf1, 10);
+
+ //3. Read bytes [25..35]. Buffered. Because the previous operation [2] performed a read-ahead operation.
+ err = fbuf.Read(25, buf1);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf1, 25);
+
+ //4. Write bytes [20..30]. Buffered. Read buffer is gone, the file buffer contains the [20..30] file area.
+ err = fbuf.Write(20, _L8("IIIIIQQQQQ"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+
+ //5. Read bytes [25..35]. Part-buffered. Part of pending writes picked up. Then the buffer is flushed.
+ err = fbuf.Read(25, buf1);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, 5);
+ TEST2(fbuf.iFileWriteCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 10);
+ TEST2(fbuf.iFileSizeCount, 0);
+
+ fbuf.ProfilerReset();
+ err = fbuf.Flush();
+ TEST2(err, KErrNone);
+
+ //All cached data should have been written to the file before the Flush() call.
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+ TEST2(fbuf.iFileFlushCount, 1);
+
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf1, 25);
+
+ //6. The buffer is empty after the last flush. Write bytes [0..10]. The file buffer contains the [0..10] file area.
+ err = fbuf.Write(0, _L8("PPOOIIUUYY"));
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 0);
+ TEST2(fbuf.iFileReadAmount, 0);
+ TEST2(fbuf.iFileWriteCount, 0);
+ TEST2(fbuf.iFileWriteAmount, 0);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+
+ //7. Read bytes [5..15]. Part buffered. Pending writes picked up. The content is written to the file.
+ err = fbuf.Read(5, buf1);
+ TEST2(err, KErrNone);
+ TEST2(fbuf.iFileReadCount, 1);
+ TEST2(fbuf.iFileReadAmount, 5);
+ TEST2(fbuf.iFileWriteCount, 1);
+ TEST2(fbuf.iFileWriteAmount, 10);
+ TEST2(fbuf.iFileSizeCount, 0);
+ fbuf.ProfilerReset();
+ VerifyFileContent(buf1, 5);
+
+ fbuf.Close();
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4141
+@SYMTestCaseDesc RFileBuf64::SetReadAheadSize() test.
+ The test iterates over all existing drives.
+ For each R/W drive a test file is created using RFileBuf64 class.
+ Then the test collects information regarding the block size, cluster size and
+ read buffer size and calls RFileBuf64::SetReadAheadSize() with these parameters
+ to check how the read-ahead buffer size will be recalculated.
+@SYMTestActions RFileBuf64::SetReadAheadSize() test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void SetReadAheadSizeTest()
+ {
+ TheTest.Printf(_L("==================\r\n"));
+ _LIT(KType1, "Not present");
+ _LIT(KType2, "Unknown");
+ _LIT(KType3, "Floppy");
+ _LIT(KType4, "Hard disk");
+ _LIT(KType5, "CD ROM");
+ _LIT(KType6, "RAM disk");
+ _LIT(KType7, "Flash");
+ _LIT(KType8, "ROM drive");
+ _LIT(KType9, "Remote drive");
+ _LIT(KType10,"NAND flash");
+ _LIT(KType11,"Rotating media");
+
+ for(TInt drive=EDriveA;drive<=EDriveZ;++drive)
+ {
+ TDriveInfo driveInfo;
+ TInt err = TheFs.Drive(driveInfo, drive);
+ if(err == KErrNone)
+ {
+ TVolumeInfo vinfo;
+ err = TheFs.Volume(vinfo, drive);
+ if(err == KErrNone)
+ {
+ TVolumeIOParamInfo vparam;
+ err = TheFs.VolumeIOParam(drive, vparam);
+ TEST2(err, KErrNone);
+ TBuf8<128> vinfoex8;
+ err = TheFs.QueryVolumeInfoExt(drive, EFileSystemSubType, vinfoex8);
+ TEST2(err, KErrNone);
+ TPtrC vinfoex((const TUint16*)(vinfoex8.Ptr() + 8), vinfoex8[0]);
+ TPtrC KMediaTypeNames[] = {KType1(), KType2(), KType3(), KType4(), KType5(), KType6(), KType7(), KType8(), KType9(), KType10(), KType11()};
+ TheTest.Printf(_L("Drive: %C:, Type: %16.16S, File System: %8.8S, Size: %d Mb.\r\n"), 'A' + drive, &KMediaTypeNames[driveInfo.iType], &vinfoex, (TInt)(vinfo.iSize / (1024 * 1024)));
+ TheTest.Printf(_L(" Size: %ld bytes.\r\n"), vinfo.iSize);
+ TheTest.Printf(_L(" Block size=%d, Cluster size=%d, Read buffer size=%d.\r\n"), vparam.iBlockSize, vparam.iClusterSize, vparam.iRecReadBufSize);
+ if(driveInfo.iType == EMediaRam || driveInfo.iType == EMediaHardDisk || driveInfo.iType == EMediaFlash || driveInfo.iType == EMediaNANDFlash)
+ {
+ TDriveUnit drvUnit(drive);
+ TDriveName drvName = drvUnit.Name();
+ TParse parse;
+ parse.Set(KTestFile2, &drvName, NULL);
+ TheDbName.Copy(parse.FullName());
+ TRAP(err, BaflUtils::EnsurePathExistsL(TheFs, TheDbName));
+ TEST(err == KErrNone || err == KErrAlreadyExists);
+ (void)TheFs.Delete(TheDbName);
+ RFileBuf64 fbuf64(8 * 1024);
+ err = fbuf64.Create(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err, KErrNone);
+ TInt readAhead = fbuf64.SetReadAheadSize(vparam.iBlockSize, vparam.iRecReadBufSize);
+ TheTest.Printf(_L(" Read-ahead size=%d.\r\n"), readAhead);
+ fbuf64.Close();
+ (void)TheFs.Delete(TheDbName);
+ }
+ }
+ else
+ {
+ TheTest.Printf(_L("Drive %C. RFs::Volume() has failed with err=%d.\r\n"), 'A' + drive, err);
+ }
+ }
+ else
+ {
+ TheTest.Printf(_L("Drive %C. RFs::Drive() has failed with err=%d.\r\n"), 'A' + drive, err);
+ }
+ }
+ TheTest.Printf(_L("==================\r\n"));
+ //
+ RFileBuf64 fbuf64(8 * 1024);//buffer capacity = 8Kb
+
+ //"ReadRecBufSize" defined and is power of two, the "BlockSize" is also defined and is power of two
+ TInt err2 = fbuf64.Create(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ TInt blockSize = 4096; TInt readRecBufSize = 2048;
+ TInt readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, readRecBufSize);
+ fbuf64.Close();
+
+ //"ReadRecBufSize" defined and is power of two but is less than the default read-ahead value
+ err2 = fbuf64.Open(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ blockSize = 0; readRecBufSize = 128;
+ readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, RFileBuf64::KDefaultReadAheadSize);
+ fbuf64.Close();
+
+ //"ReadRecBufSize" defined and is power of two but is bigger than the buffer capacity
+ err2 = fbuf64.Open(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ blockSize = -10; readRecBufSize = fbuf64.iCapacity * 2;
+ readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, fbuf64.iCapacity);
+ fbuf64.Close();
+
+ //"ReadRecBufSize" defined but is not power of two, "BlockSize" defined but is less than the default read-ahead value
+ err2 = fbuf64.Open(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ blockSize = 512; readRecBufSize = 4000;
+ readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, RFileBuf64::KDefaultReadAheadSize);
+ fbuf64.Close();
+
+ //"ReadRecBufSize" defined but is not power of two, "BlockSize" defined and is bigger than the default read-ahead value
+ err2 = fbuf64.Open(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ blockSize = 4096; readRecBufSize = 4000;
+ readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, blockSize);
+ fbuf64.Close();
+
+ //"ReadRecBufSize" defined but is not power of two, "BlockSize" defined and is bigger than the buffer capacity
+ err2 = fbuf64.Open(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ blockSize = fbuf64.iCapacity * 2; readRecBufSize = 1;
+ readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, fbuf64.iCapacity);
+ fbuf64.Close();
+
+ //"ReadRecBufSize" negative, "BlockSize" defined but is not power of two
+ err2 = fbuf64.Open(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ blockSize = 1000; readRecBufSize = -2;
+ readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, RFileBuf64::KDefaultReadAheadSize);
+ fbuf64.Close();
+
+ //"ReadRecBufSize" negative, "BlockSize" negative
+ err2 = fbuf64.Open(TheFs, TheDbName, EFileRead | EFileWrite);
+ TEST2(err2, KErrNone);
+ blockSize = -1; readRecBufSize = -2;
+ readAhead2 = fbuf64.SetReadAheadSize(blockSize, readRecBufSize);
+ TEST2(readAhead2, RFileBuf64::KDefaultReadAheadSize);
+ fbuf64.Close();
+ //
+ (void)TheFs.Delete(TheDbName);
+ }
+
+/**
+@SYMTestCaseID PDS-SQL-UT-4142
+@SYMTestCaseDesc RFileBuf64 OOM test.
+ The test calls RFileBuf64:Create(), RFileBuf64:Open() and RFileBuf64:Temp() in an OOM
+ simulation loop and verifies that no memory is leaked.
+@SYMTestActions RFileBuf64 OOM test.
+@SYMTestExpectedResults Test must not fail
+@SYMTestPriority High
+@SYMREQ REQ12106
+ REQ12109
+*/
+void OomTest(TOomTestType aOomTestType)
+ {
+ (void)TheFs.Delete(KTestFile);
+
+ if(aOomTestType == EOomOpenTest)
+ {
+ RFile64 file;
+ TInt err2 = file.Create(TheFs, KTestFile, EFileWrite | EFileRead);
+ file.Close();
+ TEST2(err2, KErrNone);
+ }
+
+ TFileName tmpFileName;
+ TInt err = KErrNoMemory;
+ TInt failingAllocationNo = 0;
+ RFileBuf64 fbuf(1024);
+ TheTest.Printf(_L("Iteration:\r\n"));
+ while(err == KErrNoMemory)
+ {
+ TheTest.Printf(_L(" %d"), ++failingAllocationNo);
+
+ MarkHandles();
+ MarkAllocatedCells();
+
+ __UHEAP_MARK;
+ __UHEAP_SETBURSTFAIL(RAllocator::EBurstFailNext, failingAllocationNo, KBurstRate);
+
+ switch(aOomTestType)
+ {
+ case EOomCreateTest:
+ err = fbuf.Create(TheFs, KTestFile, EFileWrite | EFileRead);
+ break;
+ case EOomOpenTest:
+ err = fbuf.Open(TheFs, KTestFile, EFileWrite | EFileRead);
+ break;
+ case EOomTempTest:
+ {
+ err = fbuf.Temp(TheFs, KTestDir, tmpFileName, EFileWrite | EFileRead);
+ }
+ break;
+ default:
+ TEST(0);
+ break;
+ }
+ fbuf.Close();
+
+ __UHEAP_RESET;
+ __UHEAP_MARKEND;
+
+ CheckAllocatedCells();
+ CheckHandles();
+
+ TEntry entry;
+ if(err != KErrNoMemory)
+ {
+ TEST2(err, KErrNone);
+ }
+ else if(aOomTestType == EOomCreateTest)
+ {
+ TInt err2 = TheFs.Entry(KTestFile, entry);
+ TEST2(err2, KErrNotFound);
+ }
+ else if(aOomTestType == EOomTempTest)
+ {
+ if(tmpFileName.Size() > 0)
+ {
+ TInt err2 = TheFs.Entry(tmpFileName, entry);
+ TEST2(err2, KErrNotFound);
+ }
+ }
+ }
+ TEST2(err, KErrNone);
+ TheTest.Printf(_L("\r\n=== OOM Test succeeded at heap failure rate of %d ===\r\n"), failingAllocationNo);
+
+ if(aOomTestType == EOomTempTest)
+ {
+ (void)TheFs.Delete(tmpFileName);
+ }
+ (void)TheFs.Delete(KTestFile);
+ }
+
+void DoTests()
+ {
+ TheTest.Start(_L(" @SYMTestCaseID:PDS-SQL-UT-4132 RFileBuf64 write test 1"));
+ WriteTest1();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4133 RFileBuf64 write test 2"));
+ WriteTest2();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4134 RFileBuf64 write test 3"));
+ WriteTest3();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4135 RFileBuf64 write test 4"));
+ WriteTest4();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4136 RFileBuf64 write test 5"));
+ WriteTest5();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4137 RFileBuf64 write test 6"));
+ WriteTest6();
+ TheTest.Next( _L("RFileBuf64 read test - preparation"));
+ PrepareReadTest();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4138 RFileBuf64 read test 1"));
+ ReadTest1();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4139 RFileBuf64 read test 2"));
+ ReadTest2();
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4140 RFileBuf64 read test 3"));
+ ReadTest3();
+
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4141 RFileBuf64::SetReadAheadSize() test"));
+ SetReadAheadSizeTest();
+
+ (void)TheFs.Delete(KTestFile);
+
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4142 RFileBuf64::Create() OOM test"));
+ OomTest(EOomCreateTest);
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4142 RFileBuf64::Open() OOM test"));
+ OomTest(EOomOpenTest);
+ TheTest.Next( _L(" @SYMTestCaseID:PDS-SQL-UT-4142 RFileBuf64::Temp() OOM test"));
+ OomTest(EOomTempTest);
+ }
+
+TInt E32Main()
+ {
+ TheTest.Title();
+
+ CTrapCleanup* tc = CTrapCleanup::New();
+ TheTest(tc != NULL);
+
+ __UHEAP_MARK;
+
+ TestEnvInit();
+ DeleteTestFiles();
+ DoTests();
+ TestEnvDestroy();
+
+ __UHEAP_MARKEND;
+
+ TheTest.End();
+ TheTest.Close();
+
+ delete tc;
+
+ User::Heap().Check();
+ return KErrNone;
+ }
+
+#else//_SQLPROFILER
+
+TInt E32Main()
+ {
+ TheTest.Title();
+
+ TheTest.Start(_L("This test works only if the test is built with _SQLPROFILER macro defined!"));
+ TheTest.End();
+ TheTest.Close();
+
+ return KErrNone;
+ }
+
+#endif//_SQLPROFILER