kerneltest/e32test/device/t_newldd.cpp
author Tom Cosgrove <tom.cosgrove@nokia.com>
Fri, 28 May 2010 16:29:07 +0100
changeset 30 8aab599e3476
parent 0 a41df078684a
permissions -rw-r--r--
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) 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 <e32test.h>
#include <e32def.h>
#include <e32def_private.h>
#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;
	}