kerneltest/e32test/device/t_newldd.cpp
changeset 9 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 9:96e5fb8b040d
       
     1 // Copyright (c) 2008-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 //
       
    15 
       
    16 #define __E32TEST_EXTENSION__
       
    17 #include <e32test.h>
       
    18 #include <e32def.h>
       
    19 #include <e32def_private.h>
       
    20 #include "t_newldd.h"
       
    21 #include "t_new_classes.h"
       
    22 
       
    23 RTest test(_L("Testing Operator New"));
       
    24 
       
    25 TInt RNewLddTest::DoControl(TInt aFunction)
       
    26 	{
       
    27 	return RBusLogicalChannel::DoControl(aFunction);
       
    28 	}
       
    29 
       
    30 TInt RNewLddTest::Open()
       
    31 	{
       
    32 	return DoCreate(KLddName,TVersion(0,1,1),KNullUnit,NULL,NULL);
       
    33 	}
       
    34 
       
    35 RNewLddTest lddconn;
       
    36 
       
    37 TInt TestNew()
       
    38 	{
       
    39 	return lddconn.DoControl(RNewLddTest::ENew);
       
    40 	}
       
    41 TInt TestPlacementVectorNew()
       
    42 	{
       
    43 	return lddconn.DoControl(RNewLddTest::EPlacementVectorNew);
       
    44 	}
       
    45 TInt TestVectorNew()
       
    46 	{
       
    47 	return lddconn.DoControl(RNewLddTest::EVectorNew);
       
    48 	}
       
    49 TInt TestPlacementNew()
       
    50 	{
       
    51 	return lddconn.DoControl(RNewLddTest::EPlacementNew);
       
    52 	}
       
    53 
       
    54 void UserSideTestNewOOM()
       
    55 	{
       
    56 	RDebug::Printf("User-Side: operator new OOM");
       
    57 	//OOM tests: should not throw
       
    58 	
       
    59 	#define TEST_NEW_OOM(CLASS) \
       
    60 	RDebug::Printf("new " #CLASS);\
       
    61 		{\
       
    62 		CLASS* p##CLASS = new CLASS;\
       
    63 		test_Equal(NULL, p##CLASS);\
       
    64 		}
       
    65 
       
    66 	TEST_NEW_OOM(XVeryLargeClassCtorAndDtor);
       
    67 	TEST_NEW_OOM(XVeryLargeClassCtorOnly);
       
    68 	TEST_NEW_OOM(XVeryLargeClassDtorOnly);
       
    69 	TEST_NEW_OOM(XVeryLargeClassNoTors);
       
    70 	}
       
    71 
       
    72 void UserSideTestNewConstruction()
       
    73 	{
       
    74 	RDebug::Printf("User-Side: operator new non-OOM");
       
    75 	//Non-OOM:
       
    76 	
       
    77 
       
    78 	#define TEST_NEW_CONSTRUCTION(CLASS) \
       
    79 	RDebug::Printf("new " #CLASS);\
       
    80 		{\
       
    81 		CLASS* p##CLASS = new CLASS;\
       
    82 		test_NotNull(p##CLASS);\
       
    83 		test_Equal(EConstructed, (p##CLASS)->iState);\
       
    84 		delete p##CLASS;\
       
    85 		}
       
    86 
       
    87 	TEST_NEW_CONSTRUCTION(XCtorAndDtor)
       
    88 	TEST_NEW_CONSTRUCTION(XCtorOnly)
       
    89 
       
    90 
       
    91 	#define TEST_NEW(CLASS) \
       
    92 	RDebug::Printf("new " #CLASS);\
       
    93 		{\
       
    94 		CLASS* p##CLASS = new CLASS;\
       
    95 		test_NotNull(p##CLASS);\
       
    96 		delete p##CLASS;\
       
    97 		}
       
    98 	TEST_NEW(XDtorOnly)
       
    99 	TEST_NEW(XNoTors)
       
   100 	}
       
   101 	
       
   102 void UserSideTestNew()
       
   103 	{
       
   104 	UserSideTestNewOOM();
       
   105 	UserSideTestNewConstruction();
       
   106 	}
       
   107 
       
   108 void TrappedUserSideTestNew()
       
   109 	{
       
   110 	RDebug::Printf("TRAPPED User-Side: operator new");
       
   111 	//OOM tests: should not throw
       
   112 
       
   113 	#define TEST_NEW_ELEAVE_OOM(CLASS) \
       
   114 	RDebug::Printf("new(ELeave) " #CLASS);\
       
   115 		{\
       
   116 		TRAPD(r, new(ELeave) (CLASS));\
       
   117 		test_Equal(KErrNoMemory, r);\
       
   118 		}
       
   119 
       
   120 	TEST_NEW_ELEAVE_OOM(XVeryLargeClassCtorAndDtor);
       
   121 	TEST_NEW_ELEAVE_OOM(XVeryLargeClassCtorOnly);
       
   122 	TEST_NEW_ELEAVE_OOM(XVeryLargeClassDtorOnly);
       
   123 	TEST_NEW_ELEAVE_OOM(XVeryLargeClassNoTors);
       
   124 
       
   125 
       
   126 
       
   127 	RDebug::Printf("User-Side: operator new non-OOM");
       
   128 	//Non-OOM:
       
   129 
       
   130 	#define TEST_NEW_ELEAVE(CLASS, TEST_CTOR ) \
       
   131 	RDebug::Printf("new(ELeave) " #CLASS);\
       
   132 		{\
       
   133 		CLASS* p##CLASS=NULL;\
       
   134 		TRAPD(r, p##CLASS = new(ELeave) (CLASS));\
       
   135 		test_KErrNone(r);\
       
   136 		volatile TBool testCtor=(TEST_CTOR);\
       
   137 		if(testCtor)\
       
   138 			{\
       
   139 			test_Equal(EConstructed, (p##CLASS)->iState);\
       
   140 			}\
       
   141 		delete p##CLASS;\
       
   142 		}
       
   143 
       
   144 	TEST_NEW_ELEAVE(XCtorAndDtor, ETrue);
       
   145 	TEST_NEW_ELEAVE(XCtorOnly, ETrue);
       
   146 	TEST_NEW_ELEAVE(XDtorOnly, EFalse);
       
   147 	TEST_NEW_ELEAVE(XNoTors, EFalse);
       
   148 	}
       
   149 
       
   150 
       
   151 #define TEST_ARRAY_CONSTRUCTION(ARRAY, LENGTH)\
       
   152 	{\
       
   153 	for(TInt i=0; i<(LENGTH); ++i)\
       
   154 		{\
       
   155 		test_Equal(EConstructed, ARRAY[i].iState);\
       
   156 		}\
       
   157 	}
       
   158 
       
   159 void UserSideTestVectorNew()
       
   160 	{
       
   161 	RDebug::Printf("User-Side:vector operator new");
       
   162 	RDebug::Printf("OOM tests");
       
   163 
       
   164 	#define TEST_VEC_NEW_OOM(CLASS) \
       
   165 	RDebug::Printf("new " #CLASS "[%d]", KOOMArraySize );\
       
   166 		{\
       
   167 		CLASS* p##CLASS = new CLASS[KOOMArraySize];\
       
   168 		test_Equal(NULL, p##CLASS);\
       
   169 		}
       
   170 
       
   171 	TEST_VEC_NEW_OOM(XCtorAndDtor);
       
   172 	TEST_VEC_NEW_OOM(XCtorOnly);
       
   173 	TEST_VEC_NEW_OOM(XDtorOnly);
       
   174 	TEST_VEC_NEW_OOM(XNoTors);
       
   175 	
       
   176 	RDebug::Printf("non-OOM tests");
       
   177 
       
   178 	#define TEST_VEC_NEW(CLASS, ARRAY_LENGTH, TEST_CTOR) \
       
   179 	RDebug::Printf("new " #CLASS "[%d]", ARRAY_LENGTH);\
       
   180 		{\
       
   181 		CLASS* p##CLASS = new CLASS[(ARRAY_LENGTH)];\
       
   182 		test_NotNull(p##CLASS);\
       
   183 		volatile TBool testCtor=(TEST_CTOR);\
       
   184 		if(testCtor)\
       
   185 			{\
       
   186 			TEST_ARRAY_CONSTRUCTION(p##CLASS, ARRAY_LENGTH);\
       
   187 			}\
       
   188 		delete[] p##CLASS;\
       
   189 		}
       
   190 
       
   191 	TEST_VEC_NEW(XCtorAndDtor, KTestArrayLength, ETrue);
       
   192 	TEST_VEC_NEW(XCtorOnly, KTestArrayLength, ETrue);
       
   193 	TEST_VEC_NEW(XDtorOnly, KTestArrayLength, EFalse);
       
   194 	TEST_VEC_NEW(XNoTors, KTestArrayLength, EFalse);
       
   195 	}
       
   196 
       
   197 void TrappedUserSideTestVectorNew()
       
   198 	{
       
   199 	RDebug::Printf("User-Side:vector operator new");
       
   200 	RDebug::Printf("OOM tests");
       
   201 
       
   202 	#define TEST_VEC_NEW_ELEAVE_OOM(CLASS) \
       
   203 	RDebug::Printf("new(ELeave) " #CLASS "[%d]", KOOMArraySize );\
       
   204 		{\
       
   205 	   	TRAPD(r, new(ELeave) CLASS[KOOMArraySize];)\
       
   206 		test_Equal(KErrNoMemory, r);\
       
   207 		}
       
   208 
       
   209 	TEST_VEC_NEW_ELEAVE_OOM(XCtorAndDtor);
       
   210 	TEST_VEC_NEW_ELEAVE_OOM(XCtorOnly);
       
   211 	TEST_VEC_NEW_ELEAVE_OOM(XDtorOnly);
       
   212 	TEST_VEC_NEW_ELEAVE_OOM(XNoTors);
       
   213 
       
   214 
       
   215 
       
   216 	RDebug::Printf("non-OOM tests");
       
   217 	#define TEST_VEC_NEW_ELEAVE(CLASS, ARRAY_LENGTH, TEST_CTOR) \
       
   218 	RDebug::Printf("new(ELeave) " #CLASS "[%d]", ARRAY_LENGTH);\
       
   219 		{\
       
   220 		CLASS* p##CLASS = NULL;\
       
   221 		TRAPD(r, p##CLASS = new(ELeave) CLASS[(ARRAY_LENGTH)]);\
       
   222 		test_KErrNone(r);\
       
   223 		TBool testCtor=(TEST_CTOR);\
       
   224 		if(testCtor)\
       
   225 			{\
       
   226 			TEST_ARRAY_CONSTRUCTION(p##CLASS, ARRAY_LENGTH);\
       
   227 			}\
       
   228 		delete[] p##CLASS;\
       
   229 		}
       
   230 
       
   231 	TEST_VEC_NEW_ELEAVE(XCtorAndDtor, KTestArrayLength, ETrue);
       
   232 	TEST_VEC_NEW_ELEAVE(XCtorOnly, KTestArrayLength, ETrue);
       
   233 	TEST_VEC_NEW_ELEAVE(XDtorOnly, KTestArrayLength, EFalse);
       
   234 	TEST_VEC_NEW_ELEAVE(XNoTors, KTestArrayLength, EFalse);
       
   235 	}
       
   236 
       
   237 void UserSideTestPlacementNew()
       
   238 	{
       
   239 	RDebug::Printf("::UserSideTestPlacementNew");
       
   240 	
       
   241 	#define TEST_PLACMENT_NEW(CLASS, POST_CTOR_STATE, POST_DTOR_STATE)\
       
   242 		{\
       
   243 		void* someram = User::AllocZ(sizeof(CLASS));\
       
   244 		test_NotNull(someram);\
       
   245 		RDebug::Printf("new (someram) " #CLASS);\
       
   246 		CLASS* p##CLASS = new (someram) CLASS;\
       
   247 		test_Equal(someram, p##CLASS);\
       
   248 		test_Equal(POST_CTOR_STATE, p##CLASS->iState);\
       
   249 		p##CLASS->~CLASS();\
       
   250 		test_Equal(POST_DTOR_STATE, p##CLASS->iState);\
       
   251 		User::Free(someram);\
       
   252 		p##CLASS=NULL;\
       
   253 		}\
       
   254 
       
   255 	TEST_PLACMENT_NEW(XCtorAndDtor, EConstructed, EDeconstructed);
       
   256 	TEST_PLACMENT_NEW(XCtorOnly, EConstructed, EConstructed);
       
   257 	TEST_PLACMENT_NEW(XDtorOnly, ENull, EDeconstructed);
       
   258 	TEST_PLACMENT_NEW(XNoTors, ENull, ENull);
       
   259 	}
       
   260 
       
   261 
       
   262 void UserSideTestPlacementVectorNew()
       
   263 	{
       
   264 	__UHEAP_MARK;
       
   265 
       
   266 	RDebug::Printf("::UserSideTestPlacementVectorNew");
       
   267 
       
   268 	#define TEST_VEC_PLACEMENT_NEW(CLASS, ARRAY_LENGTH, POST_CTOR_STATE, POST_DTOR_STATE)\
       
   269 	RDebug::Printf("new(someram) " #CLASS "[%d]", ARRAY_LENGTH);\
       
   270 		{\
       
   271 		void* someram = User::AllocZ(sizeof(CLASS) * ARRAY_LENGTH);\
       
   272 		test_NotNull(someram);\
       
   273 		CLASS* p##CLASS = new (someram) CLASS[(ARRAY_LENGTH)];\
       
   274 		for(TInt i=0; i<(ARRAY_LENGTH); ++i)\
       
   275 			{\
       
   276 			test_Equal(POST_CTOR_STATE, p##CLASS[i].iState);\
       
   277 			p##CLASS[i].~CLASS();\
       
   278 			test_Equal(POST_DTOR_STATE, p##CLASS[i].iState);\
       
   279 			}\
       
   280 		User::Free(someram);\
       
   281 		}
       
   282 
       
   283 	TEST_VEC_PLACEMENT_NEW(XCtorAndDtor, KTestArrayLength, EConstructed, EDeconstructed);
       
   284 	TEST_VEC_PLACEMENT_NEW(XCtorOnly, KTestArrayLength, EConstructed, EConstructed);
       
   285 	TEST_VEC_PLACEMENT_NEW(XDtorOnly, KTestArrayLength, ENull, EDeconstructed);
       
   286 	TEST_VEC_PLACEMENT_NEW(XNoTors, KTestArrayLength, ENull, ENull);
       
   287 
       
   288 	__UHEAP_MARKEND;
       
   289 	}
       
   290 
       
   291 
       
   292 TInt E32Main()
       
   293 	{
       
   294 	__UHEAP_MARK;
       
   295 
       
   296 	test.Start(_L("Testing operator new"));
       
   297 	
       
   298 	test.Next(_L("Installing LDD"));
       
   299 	TInt r=User::LoadLogicalDevice(KKInstallLddName);
       
   300 	test(r==KErrNone || r==KErrAlreadyExists);
       
   301 	
       
   302 	__KHEAP_MARK;
       
   303 
       
   304 	#define TEST_THIS(X) test.Next(_L(#X)); (X)
       
   305 	
       
   306 	TEST_THIS(UserSideTestNew());
       
   307 	TEST_THIS(UserSideTestPlacementNew());
       
   308 
       
   309 // Workaround for bug in MSVC6/CW compilers. The following test case fails on
       
   310 // WINS, WINSCW and X86 targets (not X86GCC), where the placement vector new
       
   311 // operator does not behave as expected, ultimately resulting in heap corruption
       
   312 // when the parameter to placement array new is passed on the stack.
       
   313 #if !(defined(__WINS__) || (defined(__VC32__) && (_MSC_VER < 1300)))
       
   314 	TEST_THIS(UserSideTestPlacementVectorNew());
       
   315 #else
       
   316 	test.Next(_L("Emulator and/or VC32 - Skipped: UserSideTestPlacementVectorNew"));
       
   317 #endif
       
   318 
       
   319 	TEST_THIS(UserSideTestVectorNew());
       
   320 	TEST_THIS(TrappedUserSideTestNew());
       
   321 	TEST_THIS(TrappedUserSideTestVectorNew());
       
   322 	
       
   323 	r=lddconn.Open();
       
   324 	test_KErrNone(r);
       
   325 
       
   326 	test.Next(_L("Kernel-side:Normal operator new"));
       
   327 	r = TestNew();
       
   328 	test_KErrNone(r);
       
   329 		
       
   330 	test.Next(_L("Kernel-side:Placement operator new"));
       
   331 	r = TestPlacementNew();
       
   332 	test_KErrNone(r);
       
   333 
       
   334 	test.Next(_L("Kernel-side:Placement Vector operator new"));
       
   335 	r = TestPlacementVectorNew();
       
   336 	test_KErrNone(r);
       
   337 
       
   338 	test.Next(_L("Kernel-side:Vector operator new"));
       
   339 	r = TestVectorNew();
       
   340 	test_KErrNone(r);
       
   341 
       
   342 	r = RTest::CloseHandleAndWaitForDestruction(lddconn);
       
   343 	test_KErrNone(r);
       
   344 
       
   345 	test.End();
       
   346 	test.Close();
       
   347 
       
   348 	__KHEAP_MARKEND;
       
   349 	__UHEAP_MARKEND;
       
   350 	return KErrNone;
       
   351 	}
       
   352