--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mmu/t_kblockmap.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,586 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// e32test\mmu\t_kblockmap.cpp
+// Unit tests for TKernBlockMap
+// 002 Test Initialise error checking
+// 003 Test processing of user-side block map into extent list
+// 004 Test processing of user-side block map into extent list, block size > read unit size
+// 005 Test Read error checking
+// 006 Test Read
+//
+//
+
+//! @SYMTestCaseID KBASE-T_KBLOCKMAP-0338
+//! @SYMTestType UT
+//! @SYMPREQ PREQ1110
+//! @SYMTestCaseDesc Demand Paging Kernel Blockmap tests
+//! @SYMTestActions 001 Unit tests the TKernBlockMap class
+//! @SYMTestExpectedResults All tests should pass.
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+
+#include <e32test.h>
+#include <e32debug.h>
+#include <memmodel/epoc/mmubase/kblockmap.h>
+
+RTest test(_L("T_KBLOCKMAP"));
+
+#define test_noError(x) { TInt _r = (x); if (_r < 0) HandleError(_r, __LINE__); }
+#define test_notNull(x) { TAny* _a = (TAny*)(x); if (_a == NULL) HandleNull(__LINE__); }
+#define test_equal(e, a) { TInt _e = (e); TInt _a = (a); if (_e != _a) HandleNotEqual(_e, _a, __LINE__); }
+
+void HandleError(TInt aError, TInt aLine)
+ {
+ test.Printf(_L("Error %d\n"), aError);
+ test.operator()(EFalse, aLine);
+ }
+
+void HandleNull(TInt aLine)
+ {
+ test.Printf(_L("Null value\n"));
+ test.operator()(EFalse, aLine);
+ }
+
+void HandleNotEqual(TInt aExpected, TInt aActual, TInt aLine)
+ {
+ test.Printf(_L("Expected 0x%x but got 0x%x\n"), aExpected, aActual);
+ test.operator()(EFalse, aLine);
+ }
+
+/// An list of "pod" objects which can be initialised by passing a variable number of TUints to its
+/// constructor
+template <class T>
+class CList
+ {
+public:
+ CList();
+ CList(TInt aCount, ...);
+ virtual ~CList();
+ inline TInt Count() const { return iCount; }
+ const T* Entries() const { return iEntries; }
+ const T& operator[](TInt aIndex) const;
+protected:
+ void Set(TInt aCount, VA_LIST aList);
+private:
+ const CList<T>& operator=(const CList<T>&);
+ TInt iCount;
+ T* iEntries;
+ };
+
+template <class T>
+CList<T>::CList()
+ : iCount(0), iEntries(NULL)
+ {
+ __ASSERT_COMPILE(sizeof(T) % sizeof(TUint32) == 0);
+ }
+
+template <class T>
+CList<T>::CList(TInt aCount, ...)
+ : iCount(aCount)
+ {
+ VA_LIST list;
+ VA_START(list, aCount);
+ Set(aCount, list);
+ }
+
+template <class T>
+CList<T>::~CList()
+ {
+ User::Free(iEntries);
+ iEntries = NULL;
+ }
+
+template <class T>
+void CList<T>::Set(TInt aCount, VA_LIST aList)
+ {
+ iCount = aCount;
+ test(iEntries == NULL);
+ iEntries = (T*)User::Alloc(sizeof(T) * iCount);
+ test_notNull(iEntries);
+ TInt argCount = iCount * (sizeof(T) / sizeof(TUint32));
+ for (TInt i = 0 ; i < argCount ; ++i)
+ ((TUint32*)iEntries)[i] = VA_ARG(aList, TUint32);
+ }
+
+template <class T>
+const T& CList<T>::operator[](TInt aIndex) const
+ {
+ test(aIndex < iCount);
+ return iEntries[aIndex];
+ }
+
+/// Holds all the data associated with the user-side representation of a block map
+class CBlockMap : public CList<TBlockMapEntryBase>
+ {
+public:
+ CBlockMap(TUint aBlockGranularity,
+ TUint aBlockStartOffset,
+ TInt64 aStartBlockAddress,
+ TUint aReadUnitShift,
+ TUint aCodeLengthInFile,
+ TUint aEntriesSize,
+ ...);
+ inline const SBlockMapInfoBase& Info() const { return iInfo; }
+ inline TInt ReadUnitShift() const { return iReadUnitShift; }
+ inline TInt CodeLengthInFile() const { return iCodeLengthInFile; }
+ inline TInt EntriesSize() const { return iEntriesSize; }
+private:
+ SBlockMapInfoBase iInfo;
+ TBlockMapEntryBase* iEntries;
+ TUint iReadUnitShift;
+ TUint iCodeLengthInFile;
+ TUint iEntriesSize;
+ };
+
+CBlockMap::CBlockMap(TUint aBlockGranularity,
+ TUint aBlockStartOffset,
+ TInt64 aStartBlockAddress,
+ TUint aReadUnitShift,
+ TUint aCodeLengthInFile,
+ TUint aEntriesSize,
+ ...)
+ {
+ iInfo.iBlockGranularity = aBlockGranularity;
+ iInfo.iBlockStartOffset = aBlockStartOffset;
+ iInfo.iStartBlockAddress = aStartBlockAddress;
+ // don't care about iInfo.iLocalDriveNumber for test purposes
+ iReadUnitShift = aReadUnitShift;
+ iCodeLengthInFile = aCodeLengthInFile;
+ iEntriesSize = aEntriesSize;
+ iEntries = (TBlockMapEntryBase*)User::Alloc(iEntriesSize);
+
+ VA_LIST list;
+ VA_START(list, aEntriesSize);
+ Set(iEntriesSize / sizeof(TBlockMapEntryBase), list);
+ }
+
+/// A list of extents, for comparison with those generated by the kernel block map processing code
+class CExtentList : public CList<TBlockMap::SExtent>
+ {
+public:
+ typedef TBlockMap::SExtent SExtent;
+ CExtentList(TInt aCount, ...);
+ void Dump() const;
+ };
+
+CExtentList::CExtentList(TInt aCount, ...)
+ {
+ VA_LIST list;
+ VA_START(list, aCount);
+ Set(aCount, list);
+ }
+
+void CExtentList::Dump() const
+ {
+ RDebug::Printf("CExtentList:\n");
+ const CExtentList& self = *this;
+ for (TInt i = 0 ; i < Count() ; ++i)
+ RDebug::Printf(" %d: %08x -> %08x: %08x\n", i, self[i].iDataOffset, self[i+1].iDataOffset, self[i].iBlockNumber);
+ }
+
+TBool operator==(const TBlockMap::SExtent& a, const TBlockMap::SExtent& b)
+ {
+ return a.iDataOffset == b.iDataOffset && a.iBlockNumber == b.iBlockNumber;
+ }
+
+TBool operator!=(const TBlockMap::SExtent& a, const TBlockMap::SExtent& b)
+ {
+ return !(a == b);
+ }
+
+TBool CompareExtentsEqual(const TBlockMap& aBlockMap, const CExtentList& aExtentList)
+ {
+ if (aBlockMap.Count() != aExtentList.Count())
+ return EFalse;
+ for (TInt i = 0 ; i < aBlockMap.Count() ; ++i)
+ {
+ if (aBlockMap.Extent(i) != aExtentList[i])
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+TInt MakeKernBlockMap(TBlockMap& aKbm, const CBlockMap& aUbm)
+ {
+ TBlockMapEntryBase* buffer = (TBlockMapEntryBase*)User::Alloc(aUbm.EntriesSize());
+ test_notNull(buffer);
+ Mem::Copy(buffer, aUbm.Entries(), aUbm.EntriesSize());
+ return aKbm.Initialise(aUbm.Info(),
+ buffer,
+ aUbm.EntriesSize(),
+ aUbm.ReadUnitShift(),
+ aUbm.CodeLengthInFile());
+}
+
+void MakeKernBlockMapAndTestExtents(const CBlockMap& aUbm, const CExtentList& aExpectedExtentList)
+ {
+ TBlockMap kbm;
+ test_noError(MakeKernBlockMap(kbm, aUbm));
+ TBool equal = CompareExtentsEqual(kbm, aExpectedExtentList);
+ if (!equal)
+ {
+ aExpectedExtentList.Dump();
+#ifdef _DEBUG
+ kbm.Dump();
+#endif
+ }
+ test(equal);
+ }
+
+// Tests
+
+void TestInitialiseErrors()
+ {
+ test.Next(_L("Test Initialise error checking"));
+ TBlockMap kbm;
+
+ // Block size must be a power of two
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(513, 0, 0, 9, 1, 8, 1, 0)));
+
+ // Block size must be greater than or equal to the read unit size
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 10, 1, 8, 1, 0)));
+
+ // Block start offset must be less than or equal to block size
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 513, 0, 9, 1, 8, 1, 0)));
+
+ // Block zero address must be a multiple of the block size
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 1, 9, 1, 8, 1, 0)));
+
+ // Code length in file must be greater than zero
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 0, 8, 1, 0)));
+
+ // Size of entries array must be multiple of the size of one entry
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 9, 1, 0)));
+
+ // Size of entries must be non-zero
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 0)));
+
+ // Size of block map must be greater or equal to size of data in file
+ test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 513, 8, 1, 0)));
+ }
+
+ // blockGranularity, startOffset, blockZeroAddress, readUnitShift, codeLengthInFile, entriesSize, (numberOfBlocks, startBlock)+
+
+void TestExtentList()
+ {
+ test.Next(_L("Test processing of user-side block map into extent list"));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // |= | | | | | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 0, 9, 1, 8, 1, 0),
+ CExtentList(1, 0, 0));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | |= | | | | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 512, 9, 1, 8, 1, 0),
+ CExtentList(1, 0, 1));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | | = | | | | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1, 8, 1, 0),
+ CExtentList(1, -23, 1));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | | | | = | | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1, 8, 1, 2),
+ CExtentList(1, -23, 3));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | | | | ======| | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 489, 8, 1, 2),
+ CExtentList(1, -23, 3));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | | | | ======== | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 600, 8, 2, 2),
+ CExtentList(1, -23, 3));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | | | | ==============| |== | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1100, 16, 2, 2, 1, 5),
+ CExtentList(2, -23, 3, 1001, 6));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | | | | ==============| |=======| | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1513, 16, 2, 2, 1, 5),
+ CExtentList(2, -23, 3, 1001, 6));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | | | | ==============| |=======|= | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1540, 16, 2, 2, 2, 5),
+ CExtentList(2, -23, 3, 1001, 6));
+ }
+
+void TestExtentListScaled()
+ {
+ test.Next(_L("Test processing of user-side block map into extent list, block size > read unit size"));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // |= : | : | : | : | : | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 0, 8, 1, 8, 1, 0),
+ CExtentList(1, 0, 0));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : |= : | : | : | : | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 512, 8, 1, 8, 1, 0),
+ CExtentList(1, 0, 2));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | = : | : | : | : | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 8, 1, 8, 1, 0),
+ CExtentList(1, -23, 2));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : = | : | : | : | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1, 8, 1, 0),
+ CExtentList(1, -24, 3));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : = | : | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1, 8, 1, 2),
+ CExtentList(1, -24, 7));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ==| : | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 232, 8, 1, 2),
+ CExtentList(1, -24, 7));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ==== : | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 333, 8, 2, 2),
+ CExtentList(1, -24, 7));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ======== | : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 666, 8, 2, 2),
+ CExtentList(1, -24, 7));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ==========| : | : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 744, 8, 2, 2),
+ CExtentList(1, -24, 7));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ==========| : |== : | : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 888, 16, 2, 2, 1, 5),
+ CExtentList(2, -24, 7, 744, 12));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ==========| : |=======| : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1256, 16, 2, 2, 1, 5),
+ CExtentList(2, -24, 7, 744, 12));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ==========| : |========= : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1350, 16, 2, 2, 2, 5),
+ CExtentList(2, -24, 7, 744, 12));
+ }
+
+/// Holds the expected arguments for one call to the read function
+struct SReadEntry
+ {
+ TLinAddr iBuffer;
+ TInt iBlockNumber;
+ TInt iBlockCount;
+ };
+
+/// Holds a list of expected arguments for all calls to the read function
+class CReadInfo : public CList<SReadEntry>
+ {
+public:
+ CReadInfo(TInt aReturnVal, TInt aCount, ...);
+ const SReadEntry& Next();
+ void Done() const;
+ TInt ReturnVal() const { return iReturnVal; }
+private:
+ TInt iPos;
+ TInt iReturnVal;
+ };
+
+CReadInfo::CReadInfo(TInt aReturnVal, TInt aCount, ...)
+ : iPos(0), iReturnVal(aReturnVal)
+ {
+ VA_LIST list;
+ VA_START(list, aCount);
+ Set(aCount, list);
+ }
+
+const SReadEntry& CReadInfo::Next()
+ {
+ const CList<SReadEntry>& self = *this;
+ return self[iPos++];
+ }
+
+void CReadInfo::Done() const
+ {
+ test_equal(Count(), iPos);
+ }
+
+TInt ReadFunc(TAny* aArg, TAny*, TLinAddr aBuffer, TInt aBlockNumber, TInt aBlockCount)
+ {
+ CReadInfo& info = *(CReadInfo*)aArg;
+ const SReadEntry& expected = info.Next();
+ test_equal(expected.iBuffer, aBuffer);
+ test_equal(expected.iBlockNumber, aBlockNumber);
+ test_equal(expected.iBlockCount, aBlockCount);
+ return KErrNone;
+ }
+
+void TestRead(const TBlockMap& aBlockMap,
+ TLinAddr aBuffer,
+ TInt aPos,
+ TInt aLength,
+ TInt aReadUnitShift,
+ const CReadInfo& aExpected)
+ {
+ test_equal(aExpected.ReturnVal(),
+ aBlockMap.Read(aBuffer, aPos, aLength, aReadUnitShift, ReadFunc, (TAny*)&aExpected, (TAny*)NULL));
+ aExpected.Done();
+ }
+
+void TestReadErrors()
+ {
+ test.Next(_L("Test Read error checking"));
+
+ TBlockMap kbm, kbm2;
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // |= | | | | | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ test_noError(MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 8, 1, 0)));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | : | : | : | : ==========| : |========= : | : |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ test_noError(MakeKernBlockMap(kbm2, CBlockMap(512, 280, 512, 8, 1350, 16, 2, 2, 2, 5)));
+
+ // Test read start position is outside block map
+ TestRead(kbm, 0, 1, 1, 9, CReadInfo(KErrArgument, 0));
+ TestRead(kbm2, 0, 1350, 1, 8, CReadInfo(KErrArgument, 0));
+
+ // Test read start position is negative
+ TestRead(kbm, 0, -1, 1, 9, CReadInfo(KErrArgument, 0));
+ TestRead(kbm2, 0, -1, 1, 8, CReadInfo(KErrArgument, 0));
+
+ // Test read length exceeds block map length
+ TestRead(kbm, 0, 0, 2, 9, CReadInfo(KErrArgument, 1, 0, 0, 1));
+ TestRead(kbm2, 0, 1349, 2, 8, CReadInfo(KErrArgument, 1, 0, 14, 1));
+ }
+
+void TestReads()
+ {
+ test.Next(_L("Test Read"));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // |=======================| | | | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+
+ TBlockMap kbm2;
+ test_noError(MakeKernBlockMap(kbm2, CBlockMap(512, 0, 0, 9, 1536, 8, 3, 0)));
+
+ // Test correct number of blocks read
+ TestRead(kbm2, 0, 0, 512, 9, CReadInfo(0, 1, 0, 0, 1));
+ TestRead(kbm2, 0, 0, 513, 9, CReadInfo(0, 1, 0, 0, 2));
+ TestRead(kbm2, 0, 0, 1024, 9, CReadInfo(0, 1, 0, 0, 2));
+ TestRead(kbm2, 0, 0, 1025, 9, CReadInfo(0, 1, 0, 0, 3));
+ TestRead(kbm2, 0, 0, 1536, 9, CReadInfo(0, 1, 0, 0, 3));
+
+ // Test start offset not aligned to read unit
+ TestRead(kbm2, 0, 1, 511, 9, CReadInfo(1, 1, 0, 0, 1));
+ TestRead(kbm2, 0, 256, 256, 9, CReadInfo(256, 1, 0, 0, 1));
+ TestRead(kbm2, 0, 511, 1, 9, CReadInfo(511, 1, 0, 0, 1));
+ TestRead(kbm2, 0, 513, 511, 9, CReadInfo(1, 1, 0, 1, 1));
+ TestRead(kbm2, 0, 1023, 1, 9, CReadInfo(511, 1, 0, 1, 1));
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // |=======| |=======| |=======| | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+
+ TBlockMap kbm;
+ test_noError(MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1536, 24, 1, 0, 1, 3, 1, 5)));
+
+ // Test correct block selected for read
+ TestRead(kbm, 0, 0, 1, 9, CReadInfo(0, 1, 0, 0, 1));
+ TestRead(kbm, 0, 256, 1, 9, CReadInfo(256, 1, 0, 0, 1));
+ TestRead(kbm, 0, 511, 1, 9, CReadInfo(511, 1, 0, 0, 1));
+ TestRead(kbm, 0, 512, 1, 9, CReadInfo(0, 1, 0, 3, 1));
+ TestRead(kbm, 0, 768, 1, 9, CReadInfo(256, 1, 0, 3, 1));
+ TestRead(kbm, 0, 1023, 1, 9, CReadInfo(511, 1, 0, 3, 1));
+ TestRead(kbm, 0, 1535, 1, 9, CReadInfo(511, 1, 0, 5, 1));
+
+ // Test reading multiple blocks
+ TestRead(kbm, 0, 0, 513, 9, CReadInfo(0, 2, 0, 0, 1, 512, 3, 1));
+ TestRead(kbm, 0, 0, 1024, 9, CReadInfo(0, 2, 0, 0, 1, 512, 3, 1));
+ TestRead(kbm, 0, 0, 1025, 9, CReadInfo(0, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
+ TestRead(kbm, 0, 0, 1536, 9, CReadInfo(0, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
+
+
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+ // | ====| |=======| |=======| | | | |
+ // +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
+
+ TBlockMap kbm3;
+ test_noError(MakeKernBlockMap(kbm3, CBlockMap(512, 256, 0, 9, 1280, 24, 1, 0, 1, 3, 1, 5)));
+
+ // Test correct block selected for read
+ TestRead(kbm3, 0, 0, 1, 9, CReadInfo(256, 1, 0, 0, 1));
+ TestRead(kbm3, 0, 255, 1, 9, CReadInfo(511, 1, 0, 0, 1));
+ TestRead(kbm3, 0, 256, 1, 9, CReadInfo(0, 1, 0, 3, 1));
+ TestRead(kbm3, 0, 767, 1, 9, CReadInfo(511, 1, 0, 3, 1));
+ TestRead(kbm3, 0, 768, 1, 9, CReadInfo(0, 1, 0, 5, 1));
+
+ // Test reading multiple blocks
+ TestRead(kbm3, 0, 0, 256, 9, CReadInfo(256, 1, 0, 0, 1));
+ TestRead(kbm3, 0, 0, 257, 9, CReadInfo(256, 2, 0, 0, 1, 512, 3, 1));
+ TestRead(kbm3, 0, 0, 768, 9, CReadInfo(256, 2, 0, 0, 1, 512, 3, 1));
+ TestRead(kbm3, 0, 0, 769, 9, CReadInfo(256, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
+ TestRead(kbm3, 0, 0, 1280, 9, CReadInfo(256, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
+ }
+
+TInt E32Main()
+ {
+ test.Title();
+ test.Start(_L("Unit tests the TKernBlockMap class"));
+
+ TestInitialiseErrors();
+ TestExtentList();
+ TestExtentListScaled();
+ TestReadErrors();
+ TestReads();
+
+ test.End();
+
+ return KErrNone;
+ }