os/kernelhwsrv/kerneltest/e32test/mmu/t_kblockmap.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "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 // e32test\mmu\t_kblockmap.cpp
    15 // Unit tests for TKernBlockMap
    16 // 002 Test Initialise error checking
    17 // 003 Test processing of user-side block map into extent list
    18 // 004 Test processing of user-side block map into extent list, block size > read unit size
    19 // 005 Test Read error checking
    20 // 006 Test Read
    21 // 
    22 //
    23 
    24 //! @SYMTestCaseID			KBASE-T_KBLOCKMAP-0338
    25 //! @SYMTestType			UT
    26 //! @SYMPREQ				PREQ1110
    27 //! @SYMTestCaseDesc		Demand Paging Kernel Blockmap tests
    28 //! @SYMTestActions			001 Unit tests the TKernBlockMap class
    29 //! @SYMTestExpectedResults All tests should pass.
    30 //! @SYMTestPriority        High
    31 //! @SYMTestStatus          Implemented
    32 
    33 #include <e32test.h>
    34 #include <e32debug.h>
    35 #include <memmodel/epoc/mmubase/kblockmap.h>
    36 
    37 RTest test(_L("T_KBLOCKMAP"));
    38 
    39 #define test_noError(x) { TInt _r = (x); if (_r < 0) HandleError(_r, __LINE__); }
    40 #define test_notNull(x) { TAny* _a = (TAny*)(x); if (_a == NULL) HandleNull(__LINE__); }
    41 #define test_equal(e, a) { TInt _e = (e); TInt _a = (a); if (_e != _a) HandleNotEqual(_e, _a, __LINE__); }
    42 
    43 void HandleError(TInt aError, TInt aLine)
    44 	{
    45 	test.Printf(_L("Error %d\n"), aError);
    46 	test.operator()(EFalse, aLine);
    47 	}
    48 
    49 void HandleNull(TInt aLine)
    50 	{
    51 	test.Printf(_L("Null value\n"));
    52 	test.operator()(EFalse, aLine);
    53 	}
    54 
    55 void HandleNotEqual(TInt aExpected, TInt aActual, TInt aLine)
    56 	{
    57 	test.Printf(_L("Expected 0x%x but got 0x%x\n"), aExpected, aActual);
    58 	test.operator()(EFalse, aLine);
    59 	}
    60 
    61 /// An list of "pod" objects which can be initialised by passing a variable number of TUints to its
    62 /// constructor
    63 template <class T>
    64 class CList
    65 	{
    66 public:
    67 	CList();
    68 	CList(TInt aCount, ...);
    69 	virtual ~CList();
    70 	inline TInt Count() const { return iCount; }
    71 	const T* Entries() const { return iEntries; }
    72 	const T& operator[](TInt aIndex) const;
    73 protected:
    74 	void Set(TInt aCount, VA_LIST aList);
    75 private:
    76 	const CList<T>& operator=(const CList<T>&);
    77 	TInt iCount;
    78 	T* iEntries;
    79 	};
    80 
    81 template <class T>
    82 CList<T>::CList()
    83 	: iCount(0), iEntries(NULL)
    84 	{
    85 	__ASSERT_COMPILE(sizeof(T) % sizeof(TUint32) == 0);
    86 	}
    87 
    88 template <class T>
    89 CList<T>::CList(TInt aCount, ...)
    90 	: iCount(aCount)
    91 	{
    92 	VA_LIST list;
    93 	VA_START(list, aCount);
    94 	Set(aCount, list);
    95 	}
    96 
    97 template <class T>
    98 CList<T>::~CList()
    99 	{
   100 	User::Free(iEntries);
   101 	iEntries = NULL;
   102 	}
   103 
   104 template <class T>
   105 void CList<T>::Set(TInt aCount, VA_LIST aList)
   106 	{
   107 	iCount = aCount;
   108 	test(iEntries == NULL);
   109 	iEntries = (T*)User::Alloc(sizeof(T) * iCount);
   110 	test_notNull(iEntries);
   111 	TInt argCount = iCount * (sizeof(T) / sizeof(TUint32));
   112 	for (TInt i = 0 ; i < argCount ; ++i)
   113 		((TUint32*)iEntries)[i] = VA_ARG(aList, TUint32);
   114 	}
   115 
   116 template <class T>
   117 const T& CList<T>::operator[](TInt aIndex) const
   118 	{
   119 	test(aIndex < iCount);
   120 	return iEntries[aIndex];
   121 	}
   122 
   123 /// Holds all the data associated with the user-side representation of a block map
   124 class CBlockMap : public CList<TBlockMapEntryBase>
   125 	{
   126 public:
   127 	CBlockMap(TUint aBlockGranularity,
   128 			  TUint aBlockStartOffset,
   129 			  TInt64 aStartBlockAddress,
   130 			  TUint aReadUnitShift,
   131 			  TUint aCodeLengthInFile,
   132 			  TUint aEntriesSize,
   133 			  ...);
   134 	inline const SBlockMapInfoBase& Info() const { return iInfo; }
   135 	inline TInt ReadUnitShift() const { return iReadUnitShift; }
   136 	inline TInt CodeLengthInFile() const { return iCodeLengthInFile; }
   137 	inline TInt EntriesSize() const { return iEntriesSize; }
   138 private:
   139 	SBlockMapInfoBase iInfo;
   140 	TBlockMapEntryBase* iEntries;
   141 	TUint iReadUnitShift;
   142 	TUint iCodeLengthInFile;
   143 	TUint iEntriesSize;
   144 	};
   145 
   146 CBlockMap::CBlockMap(TUint aBlockGranularity,
   147 					 TUint aBlockStartOffset,
   148 					 TInt64 aStartBlockAddress,
   149 					 TUint aReadUnitShift,
   150 					 TUint aCodeLengthInFile,
   151 					 TUint aEntriesSize,
   152 					 ...)
   153 	{
   154 	iInfo.iBlockGranularity = aBlockGranularity;
   155 	iInfo.iBlockStartOffset = aBlockStartOffset;
   156 	iInfo.iStartBlockAddress = aStartBlockAddress;
   157 	// don't care about iInfo.iLocalDriveNumber for test purposes
   158 	iReadUnitShift = aReadUnitShift;
   159 	iCodeLengthInFile = aCodeLengthInFile;
   160 	iEntriesSize = aEntriesSize;
   161 	iEntries = (TBlockMapEntryBase*)User::Alloc(iEntriesSize);
   162 
   163 	VA_LIST list;
   164 	VA_START(list, aEntriesSize);
   165 	Set(iEntriesSize / sizeof(TBlockMapEntryBase), list);
   166 	}
   167 
   168 /// A list of extents, for comparison with those generated by the kernel block map processing code
   169 class CExtentList : public CList<TBlockMap::SExtent>
   170 	{
   171 public:
   172 	typedef TBlockMap::SExtent SExtent;
   173 	CExtentList(TInt aCount, ...);
   174 	void Dump() const;
   175 	};
   176 
   177 CExtentList::CExtentList(TInt aCount, ...)
   178 	{
   179 	VA_LIST list;
   180 	VA_START(list, aCount);
   181 	Set(aCount, list);
   182 	}
   183 
   184 void CExtentList::Dump() const
   185 	{
   186 	RDebug::Printf("CExtentList:\n");
   187 	const CExtentList& self = *this;
   188 	for (TInt i = 0 ; i < Count() ; ++i)
   189 		RDebug::Printf("  %d: %08x -> %08x: %08x\n", i, self[i].iDataOffset, self[i+1].iDataOffset, self[i].iBlockNumber);
   190 	}
   191 
   192 TBool operator==(const TBlockMap::SExtent& a, const TBlockMap::SExtent& b)
   193 	{
   194 	return a.iDataOffset == b.iDataOffset && a.iBlockNumber == b.iBlockNumber;
   195 	}
   196 
   197 TBool operator!=(const TBlockMap::SExtent& a, const TBlockMap::SExtent& b)
   198 	{
   199 	return !(a == b);
   200 	}
   201 
   202 TBool CompareExtentsEqual(const TBlockMap& aBlockMap, const CExtentList& aExtentList)
   203 	{
   204 	if (aBlockMap.Count() != aExtentList.Count())
   205 		return EFalse;
   206 	for (TInt i = 0 ; i < aBlockMap.Count() ; ++i)
   207 		{
   208 		if (aBlockMap.Extent(i) != aExtentList[i])
   209 			return EFalse;
   210 		}
   211 	return ETrue;
   212 	}
   213 
   214 TInt MakeKernBlockMap(TBlockMap& aKbm, const CBlockMap& aUbm)
   215 	{
   216 	TBlockMapEntryBase* buffer = (TBlockMapEntryBase*)User::Alloc(aUbm.EntriesSize());
   217 	test_notNull(buffer);
   218 	Mem::Copy(buffer, aUbm.Entries(), aUbm.EntriesSize());
   219 	return aKbm.Initialise(aUbm.Info(),
   220 						   buffer,
   221 						   aUbm.EntriesSize(),
   222 						   aUbm.ReadUnitShift(),
   223 						   aUbm.CodeLengthInFile());
   224 }
   225 
   226 void MakeKernBlockMapAndTestExtents(const CBlockMap& aUbm, const CExtentList& aExpectedExtentList)
   227 	{
   228 	TBlockMap kbm;
   229 	test_noError(MakeKernBlockMap(kbm, aUbm));
   230 	TBool equal = CompareExtentsEqual(kbm, aExpectedExtentList);
   231 	if (!equal)
   232 		{
   233 		aExpectedExtentList.Dump();
   234 #ifdef _DEBUG
   235 		kbm.Dump();
   236 #endif
   237 		}
   238 	test(equal);
   239 	}
   240 
   241 // Tests
   242 
   243 void TestInitialiseErrors()
   244 	{
   245 	test.Next(_L("Test Initialise error checking"));
   246 	TBlockMap kbm;
   247 
   248 	// Block size must be a power of two
   249 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(513, 0, 0, 9, 1, 8, 1, 0)));
   250 
   251 	// Block size must be greater than or equal to the read unit size
   252 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 10, 1, 8, 1, 0)));
   253 
   254 	// Block start offset must be less than or equal to block size
   255 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 513, 0, 9, 1, 8, 1, 0)));
   256 
   257 	// Block zero address must be a multiple of the block size
   258 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 1, 9, 1, 8, 1, 0)));
   259 
   260 	// Code length in file must be greater than zero
   261 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 0, 8, 1, 0)));
   262 
   263 	// Size of entries array must be multiple of the size of one entry
   264 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 9, 1, 0)));
   265 
   266 	// Size of entries must be non-zero
   267 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 0)));
   268 	
   269 	// Size of block map must be greater or equal to size of data in file
   270 	test_equal(KErrArgument, MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 513, 8, 1, 0)));
   271 	}
   272 
   273 	// blockGranularity, startOffset, blockZeroAddress, readUnitShift, codeLengthInFile, entriesSize, (numberOfBlocks, startBlock)+
   274 
   275 void TestExtentList()
   276 	{
   277 	test.Next(_L("Test processing of user-side block map into extent list"));
   278 
   279 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   280 	//  |=      |       |       |       |       |       |       |       |       |
   281 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   282 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 0, 9, 1, 8, 1, 0),
   283 								   CExtentList(1, 0, 0));
   284 
   285 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   286 	//  |       |=      |       |       |       |       |       |       |       |
   287 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   288 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 512, 9, 1, 8, 1, 0),
   289 								   CExtentList(1, 0, 1));
   290 	
   291 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   292 	//  |       | =     |       |       |       |       |       |       |       |
   293 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   294 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1, 8, 1, 0),
   295 								   CExtentList(1, -23, 1));
   296 
   297 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   298 	//  |       |       |       | =     |       |       |       |       |       |
   299 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   300 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1, 8, 1, 2),
   301 								   CExtentList(1, -23, 3));
   302 
   303 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   304 	//  |       |       |       | ======|       |       |       |       |       |
   305 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   306 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 489, 8, 1, 2),
   307 								   CExtentList(1, -23, 3));
   308 
   309 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   310 	//  |       |       |       | ========      |       |       |       |       |
   311 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   312 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 600, 8, 2, 2),
   313 								   CExtentList(1, -23, 3));
   314 	
   315 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   316 	//  |       |       |       | ==============|       |==     |       |       |
   317 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   318 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1100, 16, 2, 2, 1, 5),
   319 								   CExtentList(2, -23, 3, 1001, 6));
   320 
   321 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   322 	//  |       |       |       | ==============|       |=======|       |       |
   323 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   324 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1513, 16, 2, 2, 1, 5),
   325 								   CExtentList(2, -23, 3, 1001, 6));
   326 	
   327 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   328 	//  |       |       |       | ==============|       |=======|=      |       |
   329 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   330 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 9, 1540, 16, 2, 2, 2, 5),
   331 								   CExtentList(2, -23, 3, 1001, 6));
   332 	}
   333 
   334 void TestExtentListScaled()
   335 	{
   336 	test.Next(_L("Test processing of user-side block map into extent list, block size > read unit size"));
   337 
   338 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   339 	//  |=  :   |   :   |   :   |   :   |   :   |   :   |   :   |   :   |   :   |
   340 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   341 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 0, 8, 1, 8, 1, 0),
   342 								   CExtentList(1, 0, 0));
   343 
   344 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   345 	//  |   :   |=  :   |   :   |   :   |   :   |   :   |   :   |   :   |   :   |
   346 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   347 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 0, 512, 8, 1, 8, 1, 0),
   348 								   CExtentList(1, 0, 2));
   349 	
   350 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   351 	//  |   :   | = :   |   :   |   :   |   :   |   :   |   :   |   :   |   :   |
   352 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   353 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 23, 512, 8, 1, 8, 1, 0),
   354 								   CExtentList(1, -23, 2));
   355 
   356 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   357 	//  |   :   |   : = |   :   |   :   |   :   |   :   |   :   |   :   |   :   |
   358 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   359 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1, 8, 1, 0),
   360 								   CExtentList(1, -24, 3));
   361 
   362 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   363 	//  |   :   |   :   |   :   |   : = |   :   |   :   |   :   |   :   |   :   |
   364 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   365 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1, 8, 1, 2),
   366 								   CExtentList(1, -24, 7));
   367 
   368 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   369 	//  |   :   |   :   |   :   |   : ==|   :   |   :   |   :   |   :   |   :   |
   370 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   371 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 232, 8, 1, 2),
   372 								   CExtentList(1, -24, 7));
   373 
   374 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   375 	//  |   :   |   :   |   :   |   : ====  :   |   :   |   :   |   :   |   :   |
   376 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   377 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 333, 8, 2, 2),
   378 								   CExtentList(1, -24, 7));
   379 
   380 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   381 	//  |   :   |   :   |   :   |   : ========  |   :   |   :   |   :   |   :   |
   382 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   383 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 666, 8, 2, 2),
   384 								   CExtentList(1, -24, 7));
   385 
   386 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   387 	//  |   :   |   :   |   :   |   : ==========|   :   |   :   |   :   |   :   |
   388 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   389 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 744, 8, 2, 2),
   390 								   CExtentList(1, -24, 7));
   391 
   392 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   393 	//  |   :   |   :   |   :   |   : ==========|   :   |== :   |   :   |   :   |
   394 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   395 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 888, 16, 2, 2, 1, 5),
   396 								   CExtentList(2, -24, 7, 744, 12));
   397 
   398 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   399 	//  |   :   |   :   |   :   |   : ==========|   :   |=======|   :   |   :   |
   400 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   401 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1256, 16, 2, 2, 1, 5),
   402 								   CExtentList(2, -24, 7, 744, 12));
   403 
   404 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   405 	//  |   :   |   :   |   :   |   : ==========|   :   |=========  :   |   :   |
   406 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   407 	MakeKernBlockMapAndTestExtents(CBlockMap(512, 280, 512, 8, 1350, 16, 2, 2, 2, 5),
   408 								   CExtentList(2, -24, 7, 744, 12));
   409 	}
   410 
   411 /// Holds the expected arguments for one call to the read function
   412 struct SReadEntry
   413 	{
   414 	TLinAddr iBuffer;
   415 	TInt iBlockNumber;
   416 	TInt iBlockCount;
   417 	};
   418 
   419 /// Holds a list of expected arguments for all calls to the read function
   420 class CReadInfo : public CList<SReadEntry>
   421 	{
   422 public:
   423 	CReadInfo(TInt aReturnVal, TInt aCount, ...);
   424 	const SReadEntry& Next();
   425 	void Done() const;
   426 	TInt ReturnVal() const { return iReturnVal; }
   427 private:
   428 	TInt iPos;
   429 	TInt iReturnVal;
   430 	};
   431 
   432 CReadInfo::CReadInfo(TInt aReturnVal, TInt aCount, ...)
   433 	: iPos(0), iReturnVal(aReturnVal)
   434 	{
   435 	VA_LIST list;
   436 	VA_START(list, aCount);
   437 	Set(aCount, list);
   438 	}
   439 
   440 const SReadEntry& CReadInfo::Next()
   441 	{
   442 	const CList<SReadEntry>& self = *this;
   443 	return self[iPos++];
   444 	}
   445 
   446 void CReadInfo::Done() const
   447 	{
   448 	test_equal(Count(), iPos);
   449 	}
   450 
   451 TInt ReadFunc(TAny* aArg, TAny*, TLinAddr aBuffer, TInt aBlockNumber, TInt aBlockCount)
   452 	{
   453 	CReadInfo& info = *(CReadInfo*)aArg;
   454 	const SReadEntry& expected = info.Next();
   455 	test_equal(expected.iBuffer, aBuffer);
   456 	test_equal(expected.iBlockNumber, aBlockNumber);
   457 	test_equal(expected.iBlockCount, aBlockCount);
   458 	return KErrNone;
   459 	}
   460 
   461 void TestRead(const TBlockMap& aBlockMap,
   462 			  TLinAddr aBuffer,
   463 			  TInt aPos,
   464 			  TInt aLength,
   465 			  TInt aReadUnitShift,
   466 			  const CReadInfo& aExpected)
   467 	{
   468 	test_equal(aExpected.ReturnVal(),
   469 			   aBlockMap.Read(aBuffer, aPos, aLength, aReadUnitShift, ReadFunc, (TAny*)&aExpected, (TAny*)NULL));
   470 	aExpected.Done();
   471 	}
   472 
   473 void TestReadErrors()
   474 	{
   475 	test.Next(_L("Test Read error checking"));
   476 
   477 	TBlockMap kbm, kbm2;
   478 	
   479 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   480 	//  |=      |       |       |       |       |       |       |       |       |
   481 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   482 	test_noError(MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1, 8, 1, 0)));
   483 
   484 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   485 	//  |   :   |   :   |   :   |   : ==========|   :   |=========  :   |   :   |
   486 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------	
   487 	test_noError(MakeKernBlockMap(kbm2, CBlockMap(512, 280, 512, 8, 1350, 16, 2, 2, 2, 5)));
   488 
   489 	// Test read start position is outside block map
   490 	TestRead(kbm, 0, 1, 1, 9, CReadInfo(KErrArgument, 0));
   491 	TestRead(kbm2, 0, 1350, 1, 8, CReadInfo(KErrArgument, 0));
   492 
   493 	// Test read start position is negative
   494 	TestRead(kbm, 0, -1, 1, 9, CReadInfo(KErrArgument, 0));
   495 	TestRead(kbm2, 0, -1, 1, 8, CReadInfo(KErrArgument, 0));
   496 
   497 	// Test read length exceeds block map length 
   498 	TestRead(kbm, 0, 0, 2, 9, CReadInfo(KErrArgument, 1, 0, 0, 1));
   499 	TestRead(kbm2, 0, 1349, 2, 8, CReadInfo(KErrArgument, 1, 0, 14, 1));
   500 	}
   501 
   502 void TestReads()
   503 	{
   504 	test.Next(_L("Test Read"));
   505 
   506 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   507 	//  |=======================|       |       |       |       |       |       |
   508 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   509 	
   510 	TBlockMap kbm2;
   511 	test_noError(MakeKernBlockMap(kbm2, CBlockMap(512, 0, 0, 9, 1536, 8, 3, 0)));
   512 
   513 	// Test correct number of blocks read
   514 	TestRead(kbm2, 0, 0, 512, 9, CReadInfo(0, 1, 0, 0, 1));
   515 	TestRead(kbm2, 0, 0, 513, 9, CReadInfo(0, 1, 0, 0, 2));
   516 	TestRead(kbm2, 0, 0, 1024, 9, CReadInfo(0, 1, 0, 0, 2));
   517 	TestRead(kbm2, 0, 0, 1025, 9, CReadInfo(0, 1, 0, 0, 3));
   518 	TestRead(kbm2, 0, 0, 1536, 9, CReadInfo(0, 1, 0, 0, 3));
   519 
   520 	// Test start offset not aligned to read unit
   521 	TestRead(kbm2, 0, 1, 511, 9, CReadInfo(1, 1, 0, 0, 1));
   522 	TestRead(kbm2, 0, 256, 256, 9, CReadInfo(256, 1, 0, 0, 1));
   523 	TestRead(kbm2, 0, 511, 1, 9, CReadInfo(511, 1, 0, 0, 1));
   524 	TestRead(kbm2, 0, 513, 511, 9, CReadInfo(1, 1, 0, 1, 1));
   525 	TestRead(kbm2, 0, 1023, 1, 9, CReadInfo(511, 1, 0, 1, 1));
   526 
   527 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   528 	//  |=======|       |=======|       |=======|       |       |       |       |
   529 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   530 	
   531 	TBlockMap kbm;
   532 	test_noError(MakeKernBlockMap(kbm, CBlockMap(512, 0, 0, 9, 1536, 24, 1, 0, 1, 3, 1, 5)));
   533 
   534 	// Test correct block selected for read
   535 	TestRead(kbm, 0, 0, 1, 9, CReadInfo(0, 1, 0, 0, 1));
   536 	TestRead(kbm, 0, 256, 1, 9, CReadInfo(256, 1, 0, 0, 1));
   537 	TestRead(kbm, 0, 511, 1, 9, CReadInfo(511, 1, 0, 0, 1));
   538 	TestRead(kbm, 0, 512, 1, 9, CReadInfo(0, 1, 0, 3, 1));
   539 	TestRead(kbm, 0, 768, 1, 9, CReadInfo(256, 1, 0, 3, 1));
   540 	TestRead(kbm, 0, 1023, 1, 9, CReadInfo(511, 1, 0, 3, 1));
   541 	TestRead(kbm, 0, 1535, 1, 9, CReadInfo(511, 1, 0, 5, 1));
   542 
   543 	// Test reading multiple blocks
   544 	TestRead(kbm, 0, 0, 513, 9, CReadInfo(0, 2, 0, 0, 1, 512, 3, 1));
   545 	TestRead(kbm, 0, 0, 1024, 9, CReadInfo(0, 2, 0, 0, 1, 512, 3, 1));
   546 	TestRead(kbm, 0, 0, 1025, 9, CReadInfo(0, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
   547 	TestRead(kbm, 0, 0, 1536, 9, CReadInfo(0, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
   548 
   549 
   550 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   551 	//  |   ====|       |=======|       |=======|       |       |       |       |
   552 	//  +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------
   553 	
   554 	TBlockMap kbm3;
   555 	test_noError(MakeKernBlockMap(kbm3, CBlockMap(512, 256, 0, 9, 1280, 24, 1, 0, 1, 3, 1, 5)));
   556 
   557 	// Test correct block selected for read
   558 	TestRead(kbm3, 0, 0, 1, 9, CReadInfo(256, 1, 0, 0, 1));
   559 	TestRead(kbm3, 0, 255, 1, 9, CReadInfo(511, 1, 0, 0, 1));
   560 	TestRead(kbm3, 0, 256, 1, 9, CReadInfo(0, 1, 0, 3, 1));
   561 	TestRead(kbm3, 0, 767, 1, 9, CReadInfo(511, 1, 0, 3, 1));
   562 	TestRead(kbm3, 0, 768, 1, 9, CReadInfo(0, 1, 0, 5, 1));
   563 
   564 	// Test reading multiple blocks
   565 	TestRead(kbm3, 0, 0, 256, 9, CReadInfo(256, 1, 0, 0, 1));
   566 	TestRead(kbm3, 0, 0, 257, 9, CReadInfo(256, 2, 0, 0, 1, 512, 3, 1));
   567 	TestRead(kbm3, 0, 0, 768, 9, CReadInfo(256, 2, 0, 0, 1, 512, 3, 1));
   568 	TestRead(kbm3, 0, 0, 769, 9, CReadInfo(256, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
   569 	TestRead(kbm3, 0, 0, 1280, 9, CReadInfo(256, 3, 0, 0, 1, 512, 3, 1, 1024, 5, 1));
   570 	}
   571 
   572 TInt E32Main()
   573 	{
   574 	test.Title();
   575 	test.Start(_L("Unit tests the TKernBlockMap class"));
   576 
   577 	TestInitialiseErrors();
   578 	TestExtentList();
   579 	TestExtentListScaled();
   580 	TestReadErrors();
   581 	TestReads();
   582  
   583 	test.End();
   584 
   585 	return KErrNone;
   586 	}