Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// 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;
}