diff -r 000000000000 -r a41df078684a kerneltest/e32test/device/t_newldd.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/device/t_newldd.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,352 @@ +// 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: +// + +#define __E32TEST_EXTENSION__ +#include +#include +#include +#include "t_newldd.h" +#include "t_new_classes.h" + +RTest test(_L("Testing Operator New")); + +TInt RNewLddTest::DoControl(TInt aFunction) + { + return RBusLogicalChannel::DoControl(aFunction); + } + +TInt RNewLddTest::Open() + { + return DoCreate(KLddName,TVersion(0,1,1),KNullUnit,NULL,NULL); + } + +RNewLddTest lddconn; + +TInt TestNew() + { + return lddconn.DoControl(RNewLddTest::ENew); + } +TInt TestPlacementVectorNew() + { + return lddconn.DoControl(RNewLddTest::EPlacementVectorNew); + } +TInt TestVectorNew() + { + return lddconn.DoControl(RNewLddTest::EVectorNew); + } +TInt TestPlacementNew() + { + return lddconn.DoControl(RNewLddTest::EPlacementNew); + } + +void UserSideTestNewOOM() + { + RDebug::Printf("User-Side: operator new OOM"); + //OOM tests: should not throw + + #define TEST_NEW_OOM(CLASS) \ + RDebug::Printf("new " #CLASS);\ + {\ + CLASS* p##CLASS = new CLASS;\ + test_Equal(NULL, p##CLASS);\ + } + + TEST_NEW_OOM(XVeryLargeClassCtorAndDtor); + TEST_NEW_OOM(XVeryLargeClassCtorOnly); + TEST_NEW_OOM(XVeryLargeClassDtorOnly); + TEST_NEW_OOM(XVeryLargeClassNoTors); + } + +void UserSideTestNewConstruction() + { + RDebug::Printf("User-Side: operator new non-OOM"); + //Non-OOM: + + + #define TEST_NEW_CONSTRUCTION(CLASS) \ + RDebug::Printf("new " #CLASS);\ + {\ + CLASS* p##CLASS = new CLASS;\ + test_NotNull(p##CLASS);\ + test_Equal(EConstructed, (p##CLASS)->iState);\ + delete p##CLASS;\ + } + + TEST_NEW_CONSTRUCTION(XCtorAndDtor) + TEST_NEW_CONSTRUCTION(XCtorOnly) + + + #define TEST_NEW(CLASS) \ + RDebug::Printf("new " #CLASS);\ + {\ + CLASS* p##CLASS = new CLASS;\ + test_NotNull(p##CLASS);\ + delete p##CLASS;\ + } + TEST_NEW(XDtorOnly) + TEST_NEW(XNoTors) + } + +void UserSideTestNew() + { + UserSideTestNewOOM(); + UserSideTestNewConstruction(); + } + +void TrappedUserSideTestNew() + { + RDebug::Printf("TRAPPED User-Side: operator new"); + //OOM tests: should not throw + + #define TEST_NEW_ELEAVE_OOM(CLASS) \ + RDebug::Printf("new(ELeave) " #CLASS);\ + {\ + TRAPD(r, new(ELeave) (CLASS));\ + test_Equal(KErrNoMemory, r);\ + } + + TEST_NEW_ELEAVE_OOM(XVeryLargeClassCtorAndDtor); + TEST_NEW_ELEAVE_OOM(XVeryLargeClassCtorOnly); + TEST_NEW_ELEAVE_OOM(XVeryLargeClassDtorOnly); + TEST_NEW_ELEAVE_OOM(XVeryLargeClassNoTors); + + + + RDebug::Printf("User-Side: operator new non-OOM"); + //Non-OOM: + + #define TEST_NEW_ELEAVE(CLASS, TEST_CTOR ) \ + RDebug::Printf("new(ELeave) " #CLASS);\ + {\ + CLASS* p##CLASS=NULL;\ + TRAPD(r, p##CLASS = new(ELeave) (CLASS));\ + test_KErrNone(r);\ + volatile TBool testCtor=(TEST_CTOR);\ + if(testCtor)\ + {\ + test_Equal(EConstructed, (p##CLASS)->iState);\ + }\ + delete p##CLASS;\ + } + + TEST_NEW_ELEAVE(XCtorAndDtor, ETrue); + TEST_NEW_ELEAVE(XCtorOnly, ETrue); + TEST_NEW_ELEAVE(XDtorOnly, EFalse); + TEST_NEW_ELEAVE(XNoTors, EFalse); + } + + +#define TEST_ARRAY_CONSTRUCTION(ARRAY, LENGTH)\ + {\ + for(TInt i=0; i<(LENGTH); ++i)\ + {\ + test_Equal(EConstructed, ARRAY[i].iState);\ + }\ + } + +void UserSideTestVectorNew() + { + RDebug::Printf("User-Side:vector operator new"); + RDebug::Printf("OOM tests"); + + #define TEST_VEC_NEW_OOM(CLASS) \ + RDebug::Printf("new " #CLASS "[%d]", KOOMArraySize );\ + {\ + CLASS* p##CLASS = new CLASS[KOOMArraySize];\ + test_Equal(NULL, p##CLASS);\ + } + + TEST_VEC_NEW_OOM(XCtorAndDtor); + TEST_VEC_NEW_OOM(XCtorOnly); + TEST_VEC_NEW_OOM(XDtorOnly); + TEST_VEC_NEW_OOM(XNoTors); + + RDebug::Printf("non-OOM tests"); + + #define TEST_VEC_NEW(CLASS, ARRAY_LENGTH, TEST_CTOR) \ + RDebug::Printf("new " #CLASS "[%d]", ARRAY_LENGTH);\ + {\ + CLASS* p##CLASS = new CLASS[(ARRAY_LENGTH)];\ + test_NotNull(p##CLASS);\ + volatile TBool testCtor=(TEST_CTOR);\ + if(testCtor)\ + {\ + TEST_ARRAY_CONSTRUCTION(p##CLASS, ARRAY_LENGTH);\ + }\ + delete[] p##CLASS;\ + } + + TEST_VEC_NEW(XCtorAndDtor, KTestArrayLength, ETrue); + TEST_VEC_NEW(XCtorOnly, KTestArrayLength, ETrue); + TEST_VEC_NEW(XDtorOnly, KTestArrayLength, EFalse); + TEST_VEC_NEW(XNoTors, KTestArrayLength, EFalse); + } + +void TrappedUserSideTestVectorNew() + { + RDebug::Printf("User-Side:vector operator new"); + RDebug::Printf("OOM tests"); + + #define TEST_VEC_NEW_ELEAVE_OOM(CLASS) \ + RDebug::Printf("new(ELeave) " #CLASS "[%d]", KOOMArraySize );\ + {\ + TRAPD(r, new(ELeave) CLASS[KOOMArraySize];)\ + test_Equal(KErrNoMemory, r);\ + } + + TEST_VEC_NEW_ELEAVE_OOM(XCtorAndDtor); + TEST_VEC_NEW_ELEAVE_OOM(XCtorOnly); + TEST_VEC_NEW_ELEAVE_OOM(XDtorOnly); + TEST_VEC_NEW_ELEAVE_OOM(XNoTors); + + + + RDebug::Printf("non-OOM tests"); + #define TEST_VEC_NEW_ELEAVE(CLASS, ARRAY_LENGTH, TEST_CTOR) \ + RDebug::Printf("new(ELeave) " #CLASS "[%d]", ARRAY_LENGTH);\ + {\ + CLASS* p##CLASS = NULL;\ + TRAPD(r, p##CLASS = new(ELeave) CLASS[(ARRAY_LENGTH)]);\ + test_KErrNone(r);\ + TBool testCtor=(TEST_CTOR);\ + if(testCtor)\ + {\ + TEST_ARRAY_CONSTRUCTION(p##CLASS, ARRAY_LENGTH);\ + }\ + delete[] p##CLASS;\ + } + + TEST_VEC_NEW_ELEAVE(XCtorAndDtor, KTestArrayLength, ETrue); + TEST_VEC_NEW_ELEAVE(XCtorOnly, KTestArrayLength, ETrue); + TEST_VEC_NEW_ELEAVE(XDtorOnly, KTestArrayLength, EFalse); + TEST_VEC_NEW_ELEAVE(XNoTors, KTestArrayLength, EFalse); + } + +void UserSideTestPlacementNew() + { + RDebug::Printf("::UserSideTestPlacementNew"); + + #define TEST_PLACMENT_NEW(CLASS, POST_CTOR_STATE, POST_DTOR_STATE)\ + {\ + void* someram = User::AllocZ(sizeof(CLASS));\ + test_NotNull(someram);\ + RDebug::Printf("new (someram) " #CLASS);\ + CLASS* p##CLASS = new (someram) CLASS;\ + test_Equal(someram, p##CLASS);\ + test_Equal(POST_CTOR_STATE, p##CLASS->iState);\ + p##CLASS->~CLASS();\ + test_Equal(POST_DTOR_STATE, p##CLASS->iState);\ + User::Free(someram);\ + p##CLASS=NULL;\ + }\ + + TEST_PLACMENT_NEW(XCtorAndDtor, EConstructed, EDeconstructed); + TEST_PLACMENT_NEW(XCtorOnly, EConstructed, EConstructed); + TEST_PLACMENT_NEW(XDtorOnly, ENull, EDeconstructed); + TEST_PLACMENT_NEW(XNoTors, ENull, ENull); + } + + +void UserSideTestPlacementVectorNew() + { + __UHEAP_MARK; + + RDebug::Printf("::UserSideTestPlacementVectorNew"); + + #define TEST_VEC_PLACEMENT_NEW(CLASS, ARRAY_LENGTH, POST_CTOR_STATE, POST_DTOR_STATE)\ + RDebug::Printf("new(someram) " #CLASS "[%d]", ARRAY_LENGTH);\ + {\ + void* someram = User::AllocZ(sizeof(CLASS) * ARRAY_LENGTH);\ + test_NotNull(someram);\ + CLASS* p##CLASS = new (someram) CLASS[(ARRAY_LENGTH)];\ + for(TInt i=0; i<(ARRAY_LENGTH); ++i)\ + {\ + test_Equal(POST_CTOR_STATE, p##CLASS[i].iState);\ + p##CLASS[i].~CLASS();\ + test_Equal(POST_DTOR_STATE, p##CLASS[i].iState);\ + }\ + User::Free(someram);\ + } + + TEST_VEC_PLACEMENT_NEW(XCtorAndDtor, KTestArrayLength, EConstructed, EDeconstructed); + TEST_VEC_PLACEMENT_NEW(XCtorOnly, KTestArrayLength, EConstructed, EConstructed); + TEST_VEC_PLACEMENT_NEW(XDtorOnly, KTestArrayLength, ENull, EDeconstructed); + TEST_VEC_PLACEMENT_NEW(XNoTors, KTestArrayLength, ENull, ENull); + + __UHEAP_MARKEND; + } + + +TInt E32Main() + { + __UHEAP_MARK; + + test.Start(_L("Testing operator new")); + + test.Next(_L("Installing LDD")); + TInt r=User::LoadLogicalDevice(KKInstallLddName); + test(r==KErrNone || r==KErrAlreadyExists); + + __KHEAP_MARK; + + #define TEST_THIS(X) test.Next(_L(#X)); (X) + + TEST_THIS(UserSideTestNew()); + TEST_THIS(UserSideTestPlacementNew()); + +// Workaround for bug in MSVC6/CW compilers. The following test case fails on +// WINS, WINSCW and X86 targets (not X86GCC), where the placement vector new +// operator does not behave as expected, ultimately resulting in heap corruption +// when the parameter to placement array new is passed on the stack. +#if !(defined(__WINS__) || (defined(__VC32__) && (_MSC_VER < 1300))) + TEST_THIS(UserSideTestPlacementVectorNew()); +#else + test.Next(_L("Emulator and/or VC32 - Skipped: UserSideTestPlacementVectorNew")); +#endif + + TEST_THIS(UserSideTestVectorNew()); + TEST_THIS(TrappedUserSideTestNew()); + TEST_THIS(TrappedUserSideTestVectorNew()); + + r=lddconn.Open(); + test_KErrNone(r); + + test.Next(_L("Kernel-side:Normal operator new")); + r = TestNew(); + test_KErrNone(r); + + test.Next(_L("Kernel-side:Placement operator new")); + r = TestPlacementNew(); + test_KErrNone(r); + + test.Next(_L("Kernel-side:Placement Vector operator new")); + r = TestPlacementVectorNew(); + test_KErrNone(r); + + test.Next(_L("Kernel-side:Vector operator new")); + r = TestVectorNew(); + test_KErrNone(r); + + r = RTest::CloseHandleAndWaitForDestruction(lddconn); + test_KErrNone(r); + + test.End(); + test.Close(); + + __KHEAP_MARKEND; + __UHEAP_MARKEND; + return KErrNone; + } +