sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #define __E32TEST_EXTENSION__ sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_newldd.h" sl@0: #include "t_new_classes.h" sl@0: sl@0: RTest test(_L("Testing Operator New")); sl@0: sl@0: TInt RNewLddTest::DoControl(TInt aFunction) sl@0: { sl@0: return RBusLogicalChannel::DoControl(aFunction); sl@0: } sl@0: sl@0: TInt RNewLddTest::Open() sl@0: { sl@0: return DoCreate(KLddName,TVersion(0,1,1),KNullUnit,NULL,NULL); sl@0: } sl@0: sl@0: RNewLddTest lddconn; sl@0: sl@0: TInt TestNew() sl@0: { sl@0: return lddconn.DoControl(RNewLddTest::ENew); sl@0: } sl@0: TInt TestPlacementVectorNew() sl@0: { sl@0: return lddconn.DoControl(RNewLddTest::EPlacementVectorNew); sl@0: } sl@0: TInt TestVectorNew() sl@0: { sl@0: return lddconn.DoControl(RNewLddTest::EVectorNew); sl@0: } sl@0: TInt TestPlacementNew() sl@0: { sl@0: return lddconn.DoControl(RNewLddTest::EPlacementNew); sl@0: } sl@0: sl@0: void UserSideTestNewOOM() sl@0: { sl@0: RDebug::Printf("User-Side: operator new OOM"); sl@0: //OOM tests: should not throw sl@0: sl@0: #define TEST_NEW_OOM(CLASS) \ sl@0: RDebug::Printf("new " #CLASS);\ sl@0: {\ sl@0: CLASS* p##CLASS = new CLASS;\ sl@0: test_Equal(NULL, p##CLASS);\ sl@0: } sl@0: sl@0: TEST_NEW_OOM(XVeryLargeClassCtorAndDtor); sl@0: TEST_NEW_OOM(XVeryLargeClassCtorOnly); sl@0: TEST_NEW_OOM(XVeryLargeClassDtorOnly); sl@0: TEST_NEW_OOM(XVeryLargeClassNoTors); sl@0: } sl@0: sl@0: void UserSideTestNewConstruction() sl@0: { sl@0: RDebug::Printf("User-Side: operator new non-OOM"); sl@0: //Non-OOM: sl@0: sl@0: sl@0: #define TEST_NEW_CONSTRUCTION(CLASS) \ sl@0: RDebug::Printf("new " #CLASS);\ sl@0: {\ sl@0: CLASS* p##CLASS = new CLASS;\ sl@0: test_NotNull(p##CLASS);\ sl@0: test_Equal(EConstructed, (p##CLASS)->iState);\ sl@0: delete p##CLASS;\ sl@0: } sl@0: sl@0: TEST_NEW_CONSTRUCTION(XCtorAndDtor) sl@0: TEST_NEW_CONSTRUCTION(XCtorOnly) sl@0: sl@0: sl@0: #define TEST_NEW(CLASS) \ sl@0: RDebug::Printf("new " #CLASS);\ sl@0: {\ sl@0: CLASS* p##CLASS = new CLASS;\ sl@0: test_NotNull(p##CLASS);\ sl@0: delete p##CLASS;\ sl@0: } sl@0: TEST_NEW(XDtorOnly) sl@0: TEST_NEW(XNoTors) sl@0: } sl@0: sl@0: void UserSideTestNew() sl@0: { sl@0: UserSideTestNewOOM(); sl@0: UserSideTestNewConstruction(); sl@0: } sl@0: sl@0: void TrappedUserSideTestNew() sl@0: { sl@0: RDebug::Printf("TRAPPED User-Side: operator new"); sl@0: //OOM tests: should not throw sl@0: sl@0: #define TEST_NEW_ELEAVE_OOM(CLASS) \ sl@0: RDebug::Printf("new(ELeave) " #CLASS);\ sl@0: {\ sl@0: TRAPD(r, new(ELeave) (CLASS));\ sl@0: test_Equal(KErrNoMemory, r);\ sl@0: } sl@0: sl@0: TEST_NEW_ELEAVE_OOM(XVeryLargeClassCtorAndDtor); sl@0: TEST_NEW_ELEAVE_OOM(XVeryLargeClassCtorOnly); sl@0: TEST_NEW_ELEAVE_OOM(XVeryLargeClassDtorOnly); sl@0: TEST_NEW_ELEAVE_OOM(XVeryLargeClassNoTors); sl@0: sl@0: sl@0: sl@0: RDebug::Printf("User-Side: operator new non-OOM"); sl@0: //Non-OOM: sl@0: sl@0: #define TEST_NEW_ELEAVE(CLASS, TEST_CTOR ) \ sl@0: RDebug::Printf("new(ELeave) " #CLASS);\ sl@0: {\ sl@0: CLASS* p##CLASS=NULL;\ sl@0: TRAPD(r, p##CLASS = new(ELeave) (CLASS));\ sl@0: test_KErrNone(r);\ sl@0: volatile TBool testCtor=(TEST_CTOR);\ sl@0: if(testCtor)\ sl@0: {\ sl@0: test_Equal(EConstructed, (p##CLASS)->iState);\ sl@0: }\ sl@0: delete p##CLASS;\ sl@0: } sl@0: sl@0: TEST_NEW_ELEAVE(XCtorAndDtor, ETrue); sl@0: TEST_NEW_ELEAVE(XCtorOnly, ETrue); sl@0: TEST_NEW_ELEAVE(XDtorOnly, EFalse); sl@0: TEST_NEW_ELEAVE(XNoTors, EFalse); sl@0: } sl@0: sl@0: sl@0: #define TEST_ARRAY_CONSTRUCTION(ARRAY, LENGTH)\ sl@0: {\ sl@0: for(TInt i=0; i<(LENGTH); ++i)\ sl@0: {\ sl@0: test_Equal(EConstructed, ARRAY[i].iState);\ sl@0: }\ sl@0: } sl@0: sl@0: void UserSideTestVectorNew() sl@0: { sl@0: RDebug::Printf("User-Side:vector operator new"); sl@0: RDebug::Printf("OOM tests"); sl@0: sl@0: #define TEST_VEC_NEW_OOM(CLASS) \ sl@0: RDebug::Printf("new " #CLASS "[%d]", KOOMArraySize );\ sl@0: {\ sl@0: CLASS* p##CLASS = new CLASS[KOOMArraySize];\ sl@0: test_Equal(NULL, p##CLASS);\ sl@0: } sl@0: sl@0: TEST_VEC_NEW_OOM(XCtorAndDtor); sl@0: TEST_VEC_NEW_OOM(XCtorOnly); sl@0: TEST_VEC_NEW_OOM(XDtorOnly); sl@0: TEST_VEC_NEW_OOM(XNoTors); sl@0: sl@0: RDebug::Printf("non-OOM tests"); sl@0: sl@0: #define TEST_VEC_NEW(CLASS, ARRAY_LENGTH, TEST_CTOR) \ sl@0: RDebug::Printf("new " #CLASS "[%d]", ARRAY_LENGTH);\ sl@0: {\ sl@0: CLASS* p##CLASS = new CLASS[(ARRAY_LENGTH)];\ sl@0: test_NotNull(p##CLASS);\ sl@0: volatile TBool testCtor=(TEST_CTOR);\ sl@0: if(testCtor)\ sl@0: {\ sl@0: TEST_ARRAY_CONSTRUCTION(p##CLASS, ARRAY_LENGTH);\ sl@0: }\ sl@0: delete[] p##CLASS;\ sl@0: } sl@0: sl@0: TEST_VEC_NEW(XCtorAndDtor, KTestArrayLength, ETrue); sl@0: TEST_VEC_NEW(XCtorOnly, KTestArrayLength, ETrue); sl@0: TEST_VEC_NEW(XDtorOnly, KTestArrayLength, EFalse); sl@0: TEST_VEC_NEW(XNoTors, KTestArrayLength, EFalse); sl@0: } sl@0: sl@0: void TrappedUserSideTestVectorNew() sl@0: { sl@0: RDebug::Printf("User-Side:vector operator new"); sl@0: RDebug::Printf("OOM tests"); sl@0: sl@0: #define TEST_VEC_NEW_ELEAVE_OOM(CLASS) \ sl@0: RDebug::Printf("new(ELeave) " #CLASS "[%d]", KOOMArraySize );\ sl@0: {\ sl@0: TRAPD(r, new(ELeave) CLASS[KOOMArraySize];)\ sl@0: test_Equal(KErrNoMemory, r);\ sl@0: } sl@0: sl@0: TEST_VEC_NEW_ELEAVE_OOM(XCtorAndDtor); sl@0: TEST_VEC_NEW_ELEAVE_OOM(XCtorOnly); sl@0: TEST_VEC_NEW_ELEAVE_OOM(XDtorOnly); sl@0: TEST_VEC_NEW_ELEAVE_OOM(XNoTors); sl@0: sl@0: sl@0: sl@0: RDebug::Printf("non-OOM tests"); sl@0: #define TEST_VEC_NEW_ELEAVE(CLASS, ARRAY_LENGTH, TEST_CTOR) \ sl@0: RDebug::Printf("new(ELeave) " #CLASS "[%d]", ARRAY_LENGTH);\ sl@0: {\ sl@0: CLASS* p##CLASS = NULL;\ sl@0: TRAPD(r, p##CLASS = new(ELeave) CLASS[(ARRAY_LENGTH)]);\ sl@0: test_KErrNone(r);\ sl@0: TBool testCtor=(TEST_CTOR);\ sl@0: if(testCtor)\ sl@0: {\ sl@0: TEST_ARRAY_CONSTRUCTION(p##CLASS, ARRAY_LENGTH);\ sl@0: }\ sl@0: delete[] p##CLASS;\ sl@0: } sl@0: sl@0: TEST_VEC_NEW_ELEAVE(XCtorAndDtor, KTestArrayLength, ETrue); sl@0: TEST_VEC_NEW_ELEAVE(XCtorOnly, KTestArrayLength, ETrue); sl@0: TEST_VEC_NEW_ELEAVE(XDtorOnly, KTestArrayLength, EFalse); sl@0: TEST_VEC_NEW_ELEAVE(XNoTors, KTestArrayLength, EFalse); sl@0: } sl@0: sl@0: void UserSideTestPlacementNew() sl@0: { sl@0: RDebug::Printf("::UserSideTestPlacementNew"); sl@0: sl@0: #define TEST_PLACMENT_NEW(CLASS, POST_CTOR_STATE, POST_DTOR_STATE)\ sl@0: {\ sl@0: void* someram = User::AllocZ(sizeof(CLASS));\ sl@0: test_NotNull(someram);\ sl@0: RDebug::Printf("new (someram) " #CLASS);\ sl@0: CLASS* p##CLASS = new (someram) CLASS;\ sl@0: test_Equal(someram, p##CLASS);\ sl@0: test_Equal(POST_CTOR_STATE, p##CLASS->iState);\ sl@0: p##CLASS->~CLASS();\ sl@0: test_Equal(POST_DTOR_STATE, p##CLASS->iState);\ sl@0: User::Free(someram);\ sl@0: p##CLASS=NULL;\ sl@0: }\ sl@0: sl@0: TEST_PLACMENT_NEW(XCtorAndDtor, EConstructed, EDeconstructed); sl@0: TEST_PLACMENT_NEW(XCtorOnly, EConstructed, EConstructed); sl@0: TEST_PLACMENT_NEW(XDtorOnly, ENull, EDeconstructed); sl@0: TEST_PLACMENT_NEW(XNoTors, ENull, ENull); sl@0: } sl@0: sl@0: sl@0: void UserSideTestPlacementVectorNew() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: RDebug::Printf("::UserSideTestPlacementVectorNew"); sl@0: sl@0: #define TEST_VEC_PLACEMENT_NEW(CLASS, ARRAY_LENGTH, POST_CTOR_STATE, POST_DTOR_STATE)\ sl@0: RDebug::Printf("new(someram) " #CLASS "[%d]", ARRAY_LENGTH);\ sl@0: {\ sl@0: void* someram = User::AllocZ(sizeof(CLASS) * ARRAY_LENGTH);\ sl@0: test_NotNull(someram);\ sl@0: CLASS* p##CLASS = new (someram) CLASS[(ARRAY_LENGTH)];\ sl@0: for(TInt i=0; i<(ARRAY_LENGTH); ++i)\ sl@0: {\ sl@0: test_Equal(POST_CTOR_STATE, p##CLASS[i].iState);\ sl@0: p##CLASS[i].~CLASS();\ sl@0: test_Equal(POST_DTOR_STATE, p##CLASS[i].iState);\ sl@0: }\ sl@0: User::Free(someram);\ sl@0: } sl@0: sl@0: TEST_VEC_PLACEMENT_NEW(XCtorAndDtor, KTestArrayLength, EConstructed, EDeconstructed); sl@0: TEST_VEC_PLACEMENT_NEW(XCtorOnly, KTestArrayLength, EConstructed, EConstructed); sl@0: TEST_VEC_PLACEMENT_NEW(XDtorOnly, KTestArrayLength, ENull, EDeconstructed); sl@0: TEST_VEC_PLACEMENT_NEW(XNoTors, KTestArrayLength, ENull, ENull); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: TInt E32Main() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: test.Start(_L("Testing operator new")); sl@0: sl@0: test.Next(_L("Installing LDD")); sl@0: TInt r=User::LoadLogicalDevice(KKInstallLddName); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: __KHEAP_MARK; sl@0: sl@0: #define TEST_THIS(X) test.Next(_L(#X)); (X) sl@0: sl@0: TEST_THIS(UserSideTestNew()); sl@0: TEST_THIS(UserSideTestPlacementNew()); sl@0: sl@0: // Workaround for bug in MSVC6/CW compilers. The following test case fails on sl@0: // WINS, WINSCW and X86 targets (not X86GCC), where the placement vector new sl@0: // operator does not behave as expected, ultimately resulting in heap corruption sl@0: // when the parameter to placement array new is passed on the stack. sl@0: #if !(defined(__WINS__) || (defined(__VC32__) && (_MSC_VER < 1300))) sl@0: TEST_THIS(UserSideTestPlacementVectorNew()); sl@0: #else sl@0: test.Next(_L("Emulator and/or VC32 - Skipped: UserSideTestPlacementVectorNew")); sl@0: #endif sl@0: sl@0: TEST_THIS(UserSideTestVectorNew()); sl@0: TEST_THIS(TrappedUserSideTestNew()); sl@0: TEST_THIS(TrappedUserSideTestVectorNew()); sl@0: sl@0: r=lddconn.Open(); sl@0: test_KErrNone(r); sl@0: sl@0: test.Next(_L("Kernel-side:Normal operator new")); sl@0: r = TestNew(); sl@0: test_KErrNone(r); sl@0: sl@0: test.Next(_L("Kernel-side:Placement operator new")); sl@0: r = TestPlacementNew(); sl@0: test_KErrNone(r); sl@0: sl@0: test.Next(_L("Kernel-side:Placement Vector operator new")); sl@0: r = TestPlacementVectorNew(); sl@0: test_KErrNone(r); sl@0: sl@0: test.Next(_L("Kernel-side:Vector operator new")); sl@0: r = TestVectorNew(); sl@0: test_KErrNone(r); sl@0: sl@0: r = RTest::CloseHandleAndWaitForDestruction(lddconn); sl@0: test_KErrNone(r); sl@0: sl@0: test.End(); sl@0: test.Close(); sl@0: sl@0: __KHEAP_MARKEND; sl@0: __UHEAP_MARKEND; sl@0: return KErrNone; sl@0: } sl@0: