--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/demandpaging/t_chunkheapcreate.cpp Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,379 @@
+// Copyright (c) 2008-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\demandpaging\t_chunkheapcreate.cpp
+//
+//
+
+//
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <dptest.h>
+#include <e32hal.h>
+#include <u32exec.h>
+#include <e32svr.h>
+#include <e32panic.h>
+#include "u32std.h"
+
+#include "t_dpcmn.h"
+
+enum
+ {
+ ETestLocal,
+ ETestGlobal,
+ ETestExisting,
+ };
+
+static TPtrC gGlobalDes = _L("GlobalHeap");
+
+void UseOrCreateChunk(TChunkHeapCreateInfo aCreateInfo, TInt aTestType)
+ {
+ switch(aTestType)
+ {
+ case ETestLocal:
+ aCreateInfo.SetCreateChunk(NULL);
+ break;
+
+ case ETestGlobal:
+ aCreateInfo.SetCreateChunk(&gGlobalDes);
+ break;
+
+ case ETestExisting:
+ aCreateInfo.SetUseChunk(gChunk);
+ break;
+ }
+ }
+
+/**
+Attempt to create a global or local UserHeap with the given attributes
+
+@return ETrue The chunk is paged or unpaged as expected.
+*/
+TInt UserHeapAtt(TBool aPaged, TChunkHeapCreateInfo& aCreateInfo)
+ {
+ UpdatePaged(aPaged);
+
+ RHeap* heap = UserHeap::ChunkHeap(aCreateInfo);
+
+ test_NotNull(heap);
+ RChunk chunk;
+ chunk.SetHandle(heap->ChunkHandle());
+ TBool paged = chunk.IsPaged();
+ chunk.Close();
+ return (aPaged == paged);
+ }
+
+TInt PanicUserHeap(TAny*)
+ {
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+ createInfo.SetCreateChunk(NULL);
+ createInfo.SetMode((TUint)~UserHeap::EChunkHeapMask);
+ test(UserHeapAtt(gProcessPaged, createInfo));
+ return KErrGeneral; // Shouldn't reach here.
+ }
+
+TInt PanicChunkHeapCreate(TAny* aCreateInfo)
+ {
+ TChunkHeapCreateInfo createInfo((*(TChunkHeapCreateInfo*) aCreateInfo));
+ UserHeap::ChunkHeap(createInfo);
+ return KErrGeneral; // Should never reahc here
+ }
+
+//
+// TestChunkHeapCreate
+//
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBASE-T_CHUNKHEAPCREATE-xxxx
+//! @SYMTestType UT
+//! @SYMPREQ PREQ1954
+//! @SYMTestCaseDesc Testing TChunkHeapCreateInfo
+//! Verify the chunk heap creation implementation
+//! @SYMTestActions
+//! 1. Create a local chunk by calling SetCreateChunk(NULL).
+//! Following this check the paging status of the chunk heap.
+//! 2. Create a local chunk by calling SetCreateChunk(NULL). Set the chunk heap to EPaged.
+//! Following this check the paging status of the chunk heap.
+//! 3. Create a local chunk by calling SetCreateChunk(NULL). Set the chunk heap to EUnPaged.
+//! Following this check the paging status of the chunk heap.
+//! 4. Create a heap within a local chunk and set the minimum length of the heap to be greater
+//! than the maximum length of the heap
+//! 5. Create a heap within a local chunk and set the minimum length of the heap to -1
+//! 6. Create a heap within a local chunk and set the maximum length of the heap to
+//! less than KMinHeapSize
+//! 7. Call TChunkHeapCreateInfo::SetUseChunk() on a created local chunk calling SetCreateChunk(NULL)
+//! before hand. Following this call UserHeap::ChunkHeap() and compare the heap and the chunk handles
+//! 8. Call TChunkHeapCreateInfo::SetUseChunk() on a created local chunk calling SetCreateChunk(NULL)
+//! after. Following this call UserHeap::ChunkHeap() and compare the heap and the chunk handles
+//! 9. Call TChunkHeapCreateInfo::SetSingleThread() on a created local chunk specifying EFalse.
+//! Following this call UserHeap::ChunkHeap();
+//! 10. Call TChunkHeapCreateInfo::SetSingleThread() on a created local chunk specifying ETrue.
+//! Following this call UserHeap::ChunkHeap();
+//! 11. Call TChunkHeapCreateInfo::SetAlignment() on a created local chunk specifying aAlign to
+//! be a valid value. Following this call UserHeap::ChunkHeap();
+//! 12. Call TChunkHeapCreateInfo::SetAlignment() on a created local chunk specifying aAlign to be
+//! an invalid value (-1). Following this call UserHeap::ChunkHeap();
+//! 13. Call TChunkHeapCreateInfo::SetGrowBy() on a created local chunk specifying aGrowBy to be
+//! a valid value. Following this call UserHeap::ChunkHeap(). Following this create and array of
+//! integers on the heap and check the size of the chunk.
+//! 14. Call TChunkHeapCreateInfo::SetGrowBy() on a created local chunk specifying aGrowBy to
+//! be greater than the maximum size of the chunk. Following this call UserHeap::ChunkHeap();
+//! 15. Call TChunkHeapCreateInfo::SetOffset() on a created local chunk specifying aOffset to
+//! be a valid value. Following this call UserHeap::ChunkHeap();
+//! 16. Call TChunkHeapCreateInfo:: SetMode () on a created local chunk specifying aMode to
+//! be an invalid value. Following this call UserHeap::ChunkHeap();
+//!
+//! @SYMTestExpectedResults All tests should pass.
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//----------------------------------------------------------------------------------------------
+void TestChunkHeapCreate(TInt aTestType)
+ {
+
+
+ test.Start(_L("Test UserHeap::ChunkHeap() data paging attributes"));
+ {
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+
+ UseOrCreateChunk(createInfo, aTestType);
+
+ test(UserHeapAtt(gProcessPaged, createInfo));
+
+ createInfo.SetPaging(TChunkHeapCreateInfo::EPaged);
+ test(UserHeapAtt(ETrue, createInfo));
+
+ createInfo.SetPaging(TChunkHeapCreateInfo::EUnpaged);
+ test(UserHeapAtt(EFalse, createInfo));
+ }
+
+ test.Next(_L("Test maxHeapSize < minHeapSize"));
+ {
+ TChunkHeapCreateInfo createInfo(KMinHeapSize + gPageSize, KMinHeapSize);
+ UseOrCreateChunk(createInfo, aTestType);
+ RThread thread;
+ test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicChunkHeapCreate, KDefaultStackSize, KMinHeapSize,
+ KMinHeapSize, (TAny*) &createInfo));
+
+ test_KErrNone(TestThreadExit(thread, EExitPanic, ETHeapCreateMaxLessThanMin));
+ }
+
+ test.Next(_L("Test invalid minHeapSize"));
+ {
+ TChunkHeapCreateInfo createInfo(-1, KMinHeapSize);
+ UseOrCreateChunk(createInfo, aTestType);
+ RThread thread;
+ test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicChunkHeapCreate, KDefaultStackSize, KMinHeapSize,
+ KMinHeapSize, (TAny*) &createInfo));
+
+ test_KErrNone(TestThreadExit(thread, EExitPanic, ETHeapMinLengthNegative));
+ }
+
+ test.Next(_L("Test invalid maxHeapSize"));
+ {
+ RHeap* heap;
+ TChunkHeapCreateInfo createInfo(0, 0);
+ UseOrCreateChunk(createInfo, aTestType);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ if (heap == NULL)
+ {
+ test.Printf(_L("RHeap not created"));
+ }
+ TUint maxLength = heap->MaxLength();
+ test.Printf(_L("heap max length = 0x%x\n"), maxLength);
+
+ // Need to round up to page size as RHeap maxLength is rounded
+ // up to the nearest page size
+ TUint expectedMaxSize = _ALIGN_UP(KMinHeapSize, gPageSize);
+ test_Equal(expectedMaxSize, maxLength);
+ heap->Close();
+ }
+
+ test.Next(_L("Test SetUseChunk - calling SetCreate before"));
+ {
+ RHeap* heap;
+ RChunk chunky;
+
+ TChunkCreateInfo chunkCreateInfo;
+ chunkCreateInfo.SetNormal(gPageSize, gPageSize);
+ test_KErrNone(chunky.Create(chunkCreateInfo));
+
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+
+ createInfo.SetCreateChunk(NULL);
+ createInfo.SetUseChunk(chunky);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ if (heap == NULL)
+ {
+ test.Printf(_L("RHeap not created\n"));
+ }
+ test.Printf(_L("chunkHandle = %d heapHandle = %d\n"),chunky.Handle(), heap->ChunkHandle());
+ test_Equal(chunky.Handle(), heap->ChunkHandle());
+ heap->Close();
+ }
+
+ test.Next(_L("Test SetUseChunk - calling SetCreate after"));
+ {
+ RHeap* heap;
+ RChunk chunky;
+
+ TChunkCreateInfo chunkCreateInfo;
+ chunkCreateInfo.SetNormal(gPageSize, gPageSize);
+ test_KErrNone(chunky.Create(chunkCreateInfo));
+
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+ createInfo.SetUseChunk(chunky);
+ createInfo.SetCreateChunk(NULL);
+
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ if (heap == NULL)
+ {
+ test.Printf(_L("RHeap not created\n"));
+ }
+ test.Printf(_L("chunkHandle = %d heapHandle = %d\n"),chunky.Handle(), heap->ChunkHandle());
+ TBool isSame = EFalse;
+ if (chunky.Handle() == heap->ChunkHandle())
+ isSame = ETrue;
+ test_Equal(EFalse, isSame);
+ heap->Close();
+ }
+
+ test.Next(_L("Test SetSingleThread - ETrue"));
+ {
+ RHeap* heap;
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+ UseOrCreateChunk(createInfo, aTestType);
+ createInfo.SetSingleThread(ETrue);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ test_NotNull(heap);
+ heap->Close();
+ }
+
+ test.Next(_L("Test SetSingleThread - EFalse"));
+ {
+ RHeap* heap;
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+ UseOrCreateChunk(createInfo, aTestType);
+ createInfo.SetSingleThread(EFalse);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ test_NotNull(heap);
+ heap->Close();
+ }
+
+ test.Next(_L("Test SetAlignment 0"));
+ {
+ RHeap* heap;
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+ UseOrCreateChunk(createInfo, aTestType);
+ createInfo.SetAlignment(0);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ test_NotNull(heap);
+ heap->Close();
+ }
+
+
+ test.Next(_L("Test SetAlignment -1"));
+ {
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+ UseOrCreateChunk(createInfo, aTestType);
+ createInfo.SetAlignment(-1);
+
+ RThread thread;
+ test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicChunkHeapCreate, KDefaultStackSize, KMinHeapSize,
+ KMinHeapSize, (TAny*) &createInfo));
+
+ test_KErrNone(TestThreadExit(thread, EExitPanic, ETHeapNewBadAlignment));
+ }
+
+
+ test.Next(_L("Test SetGrowby"));
+ {
+ RHeap* heap;
+ TChunkHeapCreateInfo createInfo(0, gPageSize * 10);
+ UseOrCreateChunk(createInfo, aTestType);
+ createInfo.SetGrowBy(gPageSize);
+ createInfo.SetMode(UserHeap::EChunkHeapSwitchTo);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ test_NotNull(heap);
+ RChunk chunk;
+ chunk.SetHandle(heap->ChunkHandle());
+ TInt* numBuf = new TInt[gPageSize];
+ test_NotNull(numBuf);
+ test.Printf(_L("chunkSize = %d\n"), chunk.Size());
+ test(chunk.Size() > KMinHeapGrowBy);
+ delete numBuf;
+ heap->Close();
+ }
+
+ test.Next(_L("Test SetGrowby growBy > maxSize"));
+ {
+ RHeap* heap;
+ TChunkHeapCreateInfo createInfo(0, gPageSize * 5);
+ UseOrCreateChunk(createInfo, aTestType);
+ createInfo.SetGrowBy(gPageSize * 6);
+ createInfo.SetMode(UserHeap::EChunkHeapSwitchTo);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ test_NotNull(heap);
+ RChunk chunk;
+ chunk.SetHandle(heap->ChunkHandle());
+ TInt* numBuf = new TInt[gPageSize];
+ test_Equal(NULL, numBuf);
+
+ delete numBuf;
+ heap->Close();
+ }
+
+
+ test.Next(_L("Test SetOffset "));
+ {
+ RHeap* heap;
+ TChunkHeapCreateInfo createInfo(0, gPageSize * 10);
+ UseOrCreateChunk(createInfo, aTestType);
+ createInfo.SetOffset(8);
+ createInfo.SetMode(UserHeap::EChunkHeapSwitchTo);
+ heap = (RHeap*)UserHeap::ChunkHeap(createInfo);
+ TInt heapAddr = (TInt)heap;
+ RChunk chunk;
+ chunk.SetHandle(heap->ChunkHandle());
+ test_Equal((TInt)chunk.Base() + 8, heapAddr);
+ test_NotNull(heap);
+ heap->Close();
+ }
+
+ test.Next(_L("Test UserHeap::ChunkHeap() SetMode() invalid"));
+ {
+ TChunkHeapCreateInfo createInfo(0, gPageSize);
+ UseOrCreateChunk(createInfo, aTestType);
+
+ // Test creating a UserHeap with invalid attributes panics.
+ RThread thread;
+ test_KErrNone(thread.Create(_L("Panic UserHeap"), PanicUserHeap, KDefaultStackSize,
+ KMinHeapSize, KMinHeapSize, NULL));
+ test_KErrNone(TestThreadExit(thread, EExitPanic, EHeapCreateInvalidMode));
+ }
+
+ test.End();
+ }
+
+TInt TestingTChunkHeapCreate()
+ {
+ test.Start(_L("Test TChunkHeapCreateInfo - heap within local chunk"));
+ TestChunkHeapCreate(ETestLocal);
+
+ test.Next(_L("Test TChunkHeapCreateInfo - heap within global chunk"));
+ TestChunkHeapCreate(ETestGlobal);
+
+ test.Next(_L("Test TChunkHeapCreateInfo - heap within existing chunk"));
+ TestChunkHeapCreate(ETestExisting);
+
+ test.End();
+ return 0;
+ }