Update contrib.
1 // Copyright (c) 2004-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\system\d_dobject.cpp
15 // LDD for testing RObjectIx class
19 #include <kernel/kern_priv.h>
20 #include "d_dobject.h"
21 #include "../misc/prbs.h"
25 // Handle Mutex referenced from ObjectIx.cpp (normally from sglobals.cpp).
27 DMutex* RObjectIx::HandleMutex;
30 // Constants for test sizes and stepings...
32 const TInt KDObjectTestMaxTestSize = 2000; // Bigest size to test
33 const TInt KDObjectTestStepStart = 19; // Test all values below this
34 const TInt KDObjectTestStep = 31; // Step value used when above KDObjectTestStepStart.
35 const TInt KDObjectTestLoopCount = 3; // Loop count used in some tests to repeat random testing.
42 class DObjectTestFactory : public DLogicalDevice
46 ~DObjectTestFactory();
47 virtual TInt Install();
48 virtual void GetCaps(TDes8& aDes) const;
49 virtual TInt Create(DLogicalChannelBase*& aChannel);
56 const TInt KObjectIndexMask=0x7fff;
58 class DObjectTest : public DLogicalChannelBase
61 virtual ~DObjectTest();
63 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
64 virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
66 DObjectTestFactory* iFactory;
69 TInt RObjectIxTest1(TInt aSize);
70 TInt RObjectIxTest2(TInt aSize);
71 TInt RObjectIxTest3(TInt aSize, TBool aPerformanceTest);
72 TInt RObjectIxTest4(TInt aSize);
73 TInt RObjectIxTestExerciseIx(RObjectIx& aObjectIx, TInt aSize);
74 TInt RObjectIxInvalidHandleLookupTest(TInt aSize);
75 TInt DObjectNameTest();
77 inline TInt Index(TInt aHandle) {return(aHandle&KObjectIndexMask);}
87 DOBjAndHandle* iObjAndHandle;
94 DObjectTestFactory::DObjectTestFactory()
96 Kern::MutexCreate(RObjectIx::HandleMutex, _L("HandleMutex"), KMutexOrdHandle);
99 DObjectTestFactory::~DObjectTestFactory()
101 delete RObjectIx::HandleMutex;
102 RObjectIx::HandleMutex = NULL;
105 TInt DObjectTestFactory::Create(DLogicalChannelBase*& aChannel)
107 aChannel=new DObjectTest;
111 TInt DObjectTestFactory::Install()
113 return SetName(&KDObjectTestLddName);
116 void DObjectTestFactory::GetCaps(TDes8& /* aDes */) const
118 //aDes.FillZ(aDes.MaxLength());
121 DECLARE_STANDARD_LDD()
123 return new DObjectTestFactory;
130 TInt DObjectTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
132 if (NULL == (iObjAndHandle = (DOBjAndHandle*)Kern::Alloc(KDObjectTestMaxTestSize * sizeof(DOBjAndHandle))))
137 DObjectTest::~DObjectTest()
139 delete[] iObjAndHandle;
143 //Adds a number of DObjects to RObjectIx, then removes them in the same order.
144 TInt DObjectTest::RObjectIxTest1(TInt aSize)
152 for (i=0; i<aSize; i++) //Add
154 if( (iObjAndHandle[i].iObject = new DObject) == NULL)
159 iObjAndHandle[i].iObject->iContainerID = 0;
160 r = myIx.Add(iObjAndHandle[i].iObject, 0);
167 iObjAndHandle[i].iHandle = r;
172 for (i=0; i<aSize; i++) //Remove
174 TUint32 attr = 0; // Receives the attributes of the removed handle...
176 if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
182 iObjAndHandle[i].iObject->Close(NULL);
191 //Adds a number of DObjects to RObjectIx, then removes them in the reverse order.
192 TInt DObjectTest::RObjectIxTest2(TInt aSize)
200 for (i=0; i<aSize; i++) //Add
202 if( (iObjAndHandle[i].iObject = new DObject) == NULL)
207 iObjAndHandle[i].iObject->iContainerID = 0;
208 r = myIx.Add(iObjAndHandle[i].iObject, 0);
215 iObjAndHandle[i].iHandle = r;
220 for (i=aSize-1; i>=0; i--) //Remove in reverse
222 TUint32 attr = 0; // Receives the attributes of the removed handle...
224 if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
230 iObjAndHandle[i].iObject->Close(NULL);
239 //Adds and removes random number of DObjects to/from RObjectIx.
240 TInt DObjectTest::RObjectIxTest3(TInt aSize, TBool aPerformanceTest)
246 //---Create & init the objects we need
247 for (x=0; x<aSize; x++) iObjAndHandle[x].iObject = NULL; //initialize the array
249 if (!aPerformanceTest)
252 for (x = 0; x < KDObjectTestLoopCount; x++)
255 //---Add the random number of objects (in random order)---
256 TInt toAdd=Random(iSeed)%(aSize-myIx.ActiveCount()+1);
259 index=Random(iSeed)%aSize;
260 while (iObjAndHandle[index].iObject) index=(index+1)%aSize; //Find the next NULL pointer
261 if( (iObjAndHandle[index].iObject = new DObject) == NULL)
266 r = myIx.Add(iObjAndHandle[index].iObject, 0);
269 if (!aPerformanceTest)
274 iObjAndHandle[index].iHandle = r;
277 if (!aPerformanceTest)
280 //---Remove the random number of objects (in random order)---
281 TInt toRemove=Random(iSeed)%(myIx.ActiveCount()+1);
284 index=Random(iSeed)%aSize;
285 while (!iObjAndHandle[index].iObject) index=(index+1)%aSize; //Find the next non-NULL pointer
287 TUint32 attr = 0; // Receives the attributes of the removed handle...
289 if (KErrNone != (r=myIx.Remove(iObjAndHandle[index].iHandle, object, attr)))
291 if (!aPerformanceTest)
296 iObjAndHandle[index].iObject->Close(NULL);
297 iObjAndHandle[index].iObject=NULL;
300 if(aPerformanceTest) continue;
304 //---Test data consistency---
306 for (index=0;index<aSize;index++)
308 if (iObjAndHandle[index].iObject)
312 //Test At(TInt aHandle) method
314 if (iObjAndHandle[index].iObject != myIx.At(iObjAndHandle[index].iHandle))
316 NKern::UnlockSystem();
321 NKern::UnlockSystem();
324 //Test Count(CObject* aObject) method
326 if (1!=myIx.Count(iObjAndHandle[index].iObject))
334 //Test At(CObject* aObject) method
335 if (iObjAndHandle[index].iHandle != myIx.At(iObjAndHandle[index].iObject))
344 //Test operator[](TInt index) method
346 if (iObjAndHandle[index].iObject != myIx[Index(iObjAndHandle[index].iHandle)])
348 NKern::UnlockSystem();
353 NKern::UnlockSystem();
358 if (objNum != myIx.ActiveCount())
373 //Adds a number of DObjects to RObjectIx using reserved slots, then removes
374 // them in the same order. Repeat using the reverse order.
375 TInt DObjectTest::RObjectIxTest4(TInt aSize)
384 myIx.Reserve(-aSize);
389 for (i=0; i<aSize; i++) //Add
391 if( (iObjAndHandle[i].iObject = new DObject) == NULL)
397 iObjAndHandle[i].iObject->iContainerID = 0;
398 r = myIx.Add(iObjAndHandle[i].iObject, (TUint32)RObjectIx::EReserved);
405 iObjAndHandle[i].iHandle = r;
410 TInt toRemove=Random(iSeed)%(myIx.ActiveCount()+1);
411 TInt toAdd=toRemove; // will put them all back again...
414 i=Random(iSeed)%aSize;
415 while (!iObjAndHandle[i].iObject) i=(i+1)%aSize; //Find the next non-NULL pointer
417 TUint32 attr = 0; // Receives the attributes of the removed handle...
419 if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
425 if ((attr & RObjectIx::EReserved) == 0)
429 return KErrBadHandle;
431 iObjAndHandle[i].iObject->Close(NULL);
432 iObjAndHandle[i].iObject = NULL;
439 i=Random(iSeed)%aSize;
440 while (iObjAndHandle[i].iObject) i=(i+1)%aSize; //Find the next NULL pointer
442 if( (iObjAndHandle[i].iObject = new DObject) == NULL)
448 iObjAndHandle[i].iObject->iContainerID = 0;
449 r = myIx.Add(iObjAndHandle[i].iObject, (TUint32)RObjectIx::EReserved);
456 iObjAndHandle[i].iHandle = r;
461 for (i=aSize-1; i>=0; i--) //Remove in reverse
463 TUint32 attr = 0; // Receives the attributes of the removed handle...
465 if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
471 if ((attr & RObjectIx::EReserved) == 0)
475 return KErrBadHandle;
477 iObjAndHandle[i].iObject->Close(NULL);
478 iObjAndHandle[i].iObject = NULL;
485 } // DObjectTest::RObjectIxTest4
488 // Adds a number of DObjects to RObjectIx using both normal and reserved slots, plus
489 // unused reserved slots then removes
490 // them in the same order. Repeat using the reverse order. Used in concurrent
491 // testing with multiple threads.
492 TInt DObjectTest::RObjectIxTestExerciseIx(RObjectIx& aObjectIx, TInt aSize)
499 for (i=0; i<aSize; i++) //Add and reserve (causing a Grow())...
501 // we reserve handles because it encourages grow and shrinking of the pool
502 aObjectIx.Reserve(1);
504 if( (iObjAndHandle[i].iObject = new DObject) == NULL)
508 iObjAndHandle[i].iObject->iContainerID = 0;
509 r = aObjectIx.Add(iObjAndHandle[i].iObject, i&0x1 ? (TUint32)RObjectIx::EReserved : 0);
514 iObjAndHandle[i].iHandle = r;
517 //---Test data consistency---
518 for (i=0;i<aSize;i++)
520 if (iObjAndHandle[i].iObject)
522 //Test At(TInt aHandle) method
524 if (iObjAndHandle[i].iObject != aObjectIx.At(iObjAndHandle[i].iHandle))
526 NKern::UnlockSystem();
529 NKern::UnlockSystem();
535 for (i=0; i<aSize; i++) //Remove
537 TUint32 attr = 0; // Receives the attributes of the removed handle...
538 if (KErrNone != (r=aObjectIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
543 if ((i&0x1) && ((attr & RObjectIx::EReserved) == 0))
545 return KErrBadHandle;
548 iObjAndHandle[i].iObject->Close(NULL);
549 iObjAndHandle[i].iObject = NULL;
554 for (i=0; i<aSize; i++) //Add
556 if( (iObjAndHandle[i].iObject = new DObject) == NULL)
560 iObjAndHandle[i].iObject->iContainerID = 0;
561 r = aObjectIx.Add(iObjAndHandle[i].iObject, i&0x1 ? (TUint32)RObjectIx::EReserved : 0);
566 iObjAndHandle[i].iHandle = r;
569 //---Test data consistency---
570 for (i=0;i<aSize;i++)
572 if (iObjAndHandle[i].iObject)
575 //Test At(TInt aHandle) method
576 if (iObjAndHandle[i].iObject != aObjectIx.At(iObjAndHandle[i].iHandle))
578 NKern::UnlockSystem();
581 NKern::UnlockSystem();
587 for (i=aSize-1; i>=0; i--) //Remove in reverse
589 TUint32 attr = 0; // Receives the attributes of the removed handle...
590 if (KErrNone != (r=aObjectIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
594 if ((i&0x1) && ((attr & RObjectIx::EReserved) == 0))
596 return KErrBadHandle;
599 iObjAndHandle[i].iObject->Close(NULL);
601 aObjectIx.Reserve(-1); // Remove a reserved object causing a TidyAndCompact()...
607 } // DObjectTest::RObjectIxTestExerciseIx
611 * Adds a number of DObjects to RObjectIx, tries random invalid handle to access them,
612 * then attempts removes them in the same order.
614 * @param aSize Size of handle array to use.
616 * @return KErrNone or standard error code.
618 TInt DObjectTest::RObjectIxInvalidHandleLookupTest(TInt aSize)
627 // Add in some DObjects...
629 for (i = 0; i < aSize; i++)
631 if ((iObjAndHandle[i].iObject = new DObject) == NULL)
638 iObjAndHandle[i].iObject->iContainerID = 0;
640 r = myIx.Add(iObjAndHandle[i].iObject, 0);
647 iObjAndHandle[i].iHandle = r;
653 // Randomly attempt to access handles...
655 TInt handlesToTest = aSize * KDObjectTestLoopCount;
658 for (count = 0; count < handlesToTest; count++)
661 // A handle looks like this:
663 // Bit 15 no-close flag (ignored)
664 // Bits 16-29 instance value
665 // Bit 30 thread local flag (ignored)
666 // Bit 31 special handle flag (should be 0)
669 TInt randomHandle = Kern::Random() & 0x3fff7fff;
670 TInt uniqueID = 0; // any object type!
672 object = myIx.At(randomHandle, uniqueID);
673 NKern::UnlockSystem();
678 // We've picked a valid handle, this is unlikely but check if
679 // it is really valid...
681 TBool found = EFalse;
683 for (i = 0; i < aSize; i++)
685 if (iObjAndHandle[i].iHandle == randomHandle &&
686 iObjAndHandle[i].iObject == object)
697 return KErrBadHandle;
705 // Remove the DObjects...
707 for (i = 0; i < aSize; i++)
709 TUint32 attr = 0; // Receives the attributes of the removed handle...
711 if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr)))
718 iObjAndHandle[i].iObject->Close(NULL);
725 } // DObjectTest::RObjectIxInvalidHandleLookupTest
728 TInt DObjectTest::DObjectNameTest()
730 #define TEST_GOOD_NAME(name) if (Kern::ValidateName(name) != KErrNone) return KErrBadName;
731 #define TEST_BAD_NAME(name) if (Kern::ValidateName(name) != KErrBadName) return KErrBadName;
732 #define TEST_GOOD_FULLNAME(name) if (Kern::ValidateFullName(name) != KErrNone) return KErrBadName;
733 #define TEST_BAD_FULLNAME(name) if (Kern::ValidateFullName(name) != KErrBadName) return KErrBadName;
736 _LIT(KGoodName1,"DObject1 ABCDEFGHIJKLMNOPRSTUVWXYZ0123456789");
737 _LIT(KGoodName2,"DObject2 abdefghijklmnoprstuvwxyz!\"#$%&'()+,-./;<=>@[\\]^_`{|}~");
738 _LIT(KGoodFullName1,"DObject :3");
739 _LIT(KBadName1,"DObject 5 *");
740 _LIT(KBadName2,"DObject 6 ?");
741 TUint8 badName3[] = {'D','O','b','j','e','c','t',0x00};
742 TUint8 badName4[] = {'D','O','b','j','e','c','t',0x1f};
743 TUint8 badName5[] = {'D','O','b','j','e','c','t',0x7f};
744 TUint8 badName6[] = {'D','O','b','j','e','c','t',0xff};
745 TPtr8 badNamePtr(badName3, sizeof(badName3), sizeof(badName3));
747 // Test Kern::ValidateName for good and bad names
748 TEST_GOOD_NAME(KGoodName1);
749 TEST_GOOD_NAME(KGoodName2);
750 TEST_BAD_NAME(KGoodFullName1);
751 TEST_BAD_NAME(KBadName1);
752 TEST_BAD_NAME(KBadName2);
753 TEST_BAD_NAME(badNamePtr); // already set to badName3 as no TPtr8 default constructor
754 badNamePtr.Set(badName4, sizeof(badName4), sizeof(badName4));
755 TEST_BAD_NAME(badNamePtr);
756 badNamePtr.Set(badName5, sizeof(badName5), sizeof(badName5));
757 TEST_BAD_NAME(badNamePtr);
758 badNamePtr.Set(badName6, sizeof(badName6), sizeof(badName6));
759 TEST_BAD_NAME(badNamePtr);
761 // Test Kern::ValidateFullName for good and bad full names
762 TEST_GOOD_FULLNAME(KGoodName1);
763 TEST_GOOD_FULLNAME(KGoodName2);
764 TEST_GOOD_FULLNAME(KGoodFullName1);
765 TEST_BAD_FULLNAME(KBadName1);
766 TEST_BAD_FULLNAME(KBadName2);
767 badNamePtr.Set(badName3, sizeof(badName3), sizeof(badName3));
768 TEST_BAD_FULLNAME(badNamePtr);
769 badNamePtr.Set(badName4, sizeof(badName4), sizeof(badName4));
770 TEST_BAD_FULLNAME(badNamePtr);
771 badNamePtr.Set(badName5, sizeof(badName5), sizeof(badName5));
772 TEST_BAD_FULLNAME(badNamePtr);
773 badNamePtr.Set(badName6, sizeof(badName6), sizeof(badName6));
774 TEST_BAD_FULLNAME(badNamePtr);
779 TInt DObjectTest::Request(TInt aFunction, TAny* a1, TAny* a2)
787 TRequestStatus* s=(TRequestStatus*)a1;
788 kumemget32(args,a2,sizeof(args));
792 case RTestDObject::ERObjectIxTest1:
793 duration = NKern::TickCount();
795 NKern::ThreadEnterCS();
796 for (i = 1; i < KDObjectTestMaxTestSize; i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep)
797 if (KErrNone != (r=RObjectIxTest1(i)))
799 NKern::ThreadLeaveCS();
800 Kern::RequestComplete(s, r);
803 NKern::ThreadLeaveCS();
805 duration = NKern::TickCount() - duration;
806 kumemput32(args[0], &duration, sizeof(TInt));
808 Kern::RequestComplete(s,KErrNone);
811 case RTestDObject::ERObjectIxTest2:
812 duration = NKern::TickCount();
814 NKern::ThreadEnterCS();
815 for (i = 1; i < KDObjectTestMaxTestSize; i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep)
816 if (KErrNone != (r=RObjectIxTest2(i)))
818 NKern::ThreadLeaveCS();
819 Kern::RequestComplete(s, r);
823 NKern::ThreadLeaveCS();
825 duration = NKern::TickCount() - duration;
826 kumemput32(args[0], &duration, sizeof(TInt));
828 Kern::RequestComplete(s,KErrNone);
831 case RTestDObject::ERObjectIxTest3:
832 kumemget32(¶m, args[0], sizeof(param));
834 duration = NKern::TickCount();
835 iSeed[0] = param.iSeed[0];
836 iSeed[1] = param.iSeed[1];
837 NKern::ThreadEnterCS();
838 for (i = 1; i < KDObjectTestMaxTestSize; i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep)
839 if (KErrNone != (r=RObjectIxTest3(i, param.iPerformanceTest)))
841 NKern::ThreadLeaveCS();
842 Kern::RequestComplete(s, r);
845 NKern::ThreadLeaveCS();
847 duration = NKern::TickCount() - duration;
848 kumemput32(&((SParam*)args[0])->duration, &duration, sizeof(TInt));
850 Kern::RequestComplete(s,KErrNone);
853 case RTestDObject::ERObjectIxTest4:
854 duration = NKern::TickCount();
856 NKern::ThreadEnterCS();
857 for (i = 1; i < KDObjectTestMaxTestSize; i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep)
858 if (KErrNone != (r=RObjectIxTest4(i)))
860 NKern::ThreadLeaveCS();
861 Kern::RequestComplete(s, r);
864 NKern::ThreadLeaveCS();
866 duration = NKern::TickCount() - duration;
867 kumemput32(args[0], &duration, sizeof(TInt));
869 Kern::RequestComplete(s,KErrNone);
872 case RTestDObject::ERObjectIxThreadTestCreateIx:
873 //RTestDObject::RObjectIxThreadTestCreateIx(void*& aRObjectIxPtr);
875 RObjectIx* threadTestObjectIx = NULL;
877 NKern::ThreadEnterCS();
878 threadTestObjectIx = new RObjectIx();
879 if (threadTestObjectIx == NULL)
881 NKern::ThreadLeaveCS();
886 NKern::ThreadLeaveCS();
888 kumemput32(args[0], &threadTestObjectIx, sizeof(RObjectIx*));
891 Kern::RequestComplete(s, r);
896 case RTestDObject::ERObjectIxThreadTestExerciseIx:
897 //RTestDObject::RObjectIxThreadTestExerciseIx(void* aRObjectIxPtr);
899 RObjectIx* threadTestObjectIx = (RObjectIx*) args[0];
901 NKern::ThreadEnterCS();
902 for (i = 1; i < KDObjectTestMaxTestSize; i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep)
904 if (KErrNone != (r=RObjectIxTestExerciseIx(*threadTestObjectIx, i)))
906 NKern::ThreadLeaveCS();
907 Kern::RequestComplete(s, r);
911 NKern::ThreadLeaveCS();
913 Kern::RequestComplete(s, KErrNone);
918 case RTestDObject::ERObjectIxThreadTestFreeIx:
919 //RTestDObject::RObjectIxThreadTestFreeIx(void* aRObjectIxPtr)
921 RObjectIx* threadTestObjectIx = (RObjectIx*) args[0];
923 NKern::ThreadEnterCS();
924 threadTestObjectIx->Check(0);
925 threadTestObjectIx->Close(NULL);
926 delete threadTestObjectIx;
927 threadTestObjectIx = NULL;
928 NKern::ThreadLeaveCS();
930 Kern::RequestComplete(s, KErrNone);
935 case RTestDObject::ERObjectIxInvalidHandleLookupTest:
936 //RTestDObject::InvalidHandleLookupTest()
938 NKern::ThreadEnterCS();
939 for (i = 1; i < KDObjectTestMaxTestSize; i = i<KDObjectTestStepStart?i+1:i+KDObjectTestStep)
941 if (KErrNone != (r=RObjectIxInvalidHandleLookupTest(i)))
943 NKern::ThreadLeaveCS();
944 Kern::RequestComplete(s, r);
948 NKern::ThreadLeaveCS();
950 Kern::RequestComplete(s, r);
954 case RTestDObject::EDObjectNameTest:
956 r = DObjectNameTest();
957 Kern::RequestComplete(s, r);
961 r = KErrNotSupported;