sl@0: // Copyright (c) 2004-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: // e32test\system\d_dobject.cpp sl@0: // LDD for testing RObjectIx class sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include "d_dobject.h" sl@0: #include "../misc/prbs.h" sl@0: sl@0: sl@0: // sl@0: // Handle Mutex referenced from ObjectIx.cpp (normally from sglobals.cpp). sl@0: // sl@0: DMutex* RObjectIx::HandleMutex; sl@0: sl@0: // sl@0: // Constants for test sizes and stepings... sl@0: // sl@0: const TInt KDObjectTestMaxTestSize = 2000; // Bigest size to test sl@0: const TInt KDObjectTestStepStart = 19; // Test all values below this sl@0: const TInt KDObjectTestStep = 31; // Step value used when above KDObjectTestStepStart. sl@0: const TInt KDObjectTestLoopCount = 3; // Loop count used in some tests to repeat random testing. sl@0: sl@0: sl@0: // sl@0: // LDD factory sl@0: // sl@0: sl@0: class DObjectTestFactory : public DLogicalDevice sl@0: { sl@0: public: sl@0: DObjectTestFactory(); sl@0: ~DObjectTestFactory(); sl@0: virtual TInt Install(); sl@0: virtual void GetCaps(TDes8& aDes) const; sl@0: virtual TInt Create(DLogicalChannelBase*& aChannel); sl@0: public: sl@0: }; sl@0: sl@0: // sl@0: // Logical Channel sl@0: // sl@0: const TInt KObjectIndexMask=0x7fff; sl@0: sl@0: class DObjectTest : public DLogicalChannelBase sl@0: { sl@0: public: sl@0: virtual ~DObjectTest(); sl@0: protected: sl@0: virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); sl@0: virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2); sl@0: public: sl@0: DObjectTestFactory* iFactory; sl@0: sl@0: private: sl@0: TInt RObjectIxTest1(TInt aSize); sl@0: TInt RObjectIxTest2(TInt aSize); sl@0: TInt RObjectIxTest3(TInt aSize, TBool aPerformanceTest); sl@0: TInt RObjectIxTest4(TInt aSize); sl@0: TInt RObjectIxTestExerciseIx(RObjectIx& aObjectIx, TInt aSize); sl@0: TInt RObjectIxInvalidHandleLookupTest(TInt aSize); sl@0: TInt DObjectNameTest(); sl@0: sl@0: inline TInt Index(TInt aHandle) {return(aHandle&KObjectIndexMask);} sl@0: sl@0: private: sl@0: struct DOBjAndHandle sl@0: { sl@0: DObject* iObject; sl@0: TInt iHandle; sl@0: }; sl@0: sl@0: TUint iSeed[2]; sl@0: DOBjAndHandle* iObjAndHandle; sl@0: }; sl@0: sl@0: // sl@0: // LDD factory sl@0: // sl@0: sl@0: DObjectTestFactory::DObjectTestFactory() sl@0: { sl@0: Kern::MutexCreate(RObjectIx::HandleMutex, _L("HandleMutex"), KMutexOrdHandle); sl@0: } sl@0: sl@0: DObjectTestFactory::~DObjectTestFactory() sl@0: { sl@0: delete RObjectIx::HandleMutex; sl@0: RObjectIx::HandleMutex = NULL; sl@0: } sl@0: sl@0: TInt DObjectTestFactory::Create(DLogicalChannelBase*& aChannel) sl@0: { sl@0: aChannel=new DObjectTest; sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DObjectTestFactory::Install() sl@0: { sl@0: return SetName(&KDObjectTestLddName); sl@0: } sl@0: sl@0: void DObjectTestFactory::GetCaps(TDes8& /* aDes */) const sl@0: { sl@0: //aDes.FillZ(aDes.MaxLength()); sl@0: } sl@0: sl@0: DECLARE_STANDARD_LDD() sl@0: { sl@0: return new DObjectTestFactory; sl@0: } sl@0: sl@0: // sl@0: // Logical Channel sl@0: // sl@0: sl@0: TInt DObjectTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/) sl@0: { sl@0: if (NULL == (iObjAndHandle = (DOBjAndHandle*)Kern::Alloc(KDObjectTestMaxTestSize * sizeof(DOBjAndHandle)))) sl@0: return KErrNoMemory; sl@0: return KErrNone; sl@0: } sl@0: sl@0: DObjectTest::~DObjectTest() sl@0: { sl@0: delete[] iObjAndHandle; sl@0: } sl@0: sl@0: sl@0: //Adds a number of DObjects to RObjectIx, then removes them in the same order. sl@0: TInt DObjectTest::RObjectIxTest1(TInt aSize) sl@0: { sl@0: TInt i,r; sl@0: DObject* object; sl@0: RObjectIx myIx; sl@0: sl@0: myIx.Check(0); sl@0: sl@0: for (i=0; iiContainerID = 0; sl@0: r = myIx.Add(iObjAndHandle[i].iObject, 0); sl@0: if (r<0) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iHandle = r; sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: sl@0: for (i=0; iClose(NULL); sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: //Adds a number of DObjects to RObjectIx, then removes them in the reverse order. sl@0: TInt DObjectTest::RObjectIxTest2(TInt aSize) sl@0: { sl@0: TInt i,r; sl@0: DObject* object; sl@0: RObjectIx myIx; sl@0: sl@0: myIx.Check(0); sl@0: sl@0: for (i=0; iiContainerID = 0; sl@0: r = myIx.Add(iObjAndHandle[i].iObject, 0); sl@0: if (r<0) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iHandle = r; sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: sl@0: for (i=aSize-1; i>=0; i--) //Remove in reverse sl@0: { sl@0: TUint32 attr = 0; // Receives the attributes of the removed handle... sl@0: sl@0: if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iObject->Close(NULL); sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: //Adds and removes random number of DObjects to/from RObjectIx. sl@0: TInt DObjectTest::RObjectIxTest3(TInt aSize, TBool aPerformanceTest) sl@0: { sl@0: TInt index, x, r; sl@0: DObject* object; sl@0: RObjectIx myIx; sl@0: sl@0: //---Create & init the objects we need sl@0: for (x=0; xClose(NULL); sl@0: iObjAndHandle[index].iObject=NULL; sl@0: } sl@0: sl@0: if(aPerformanceTest) continue; sl@0: sl@0: myIx.Check(0); sl@0: sl@0: //---Test data consistency--- sl@0: TInt objNum=0; sl@0: for (index=0;indexiContainerID = 0; sl@0: r = myIx.Add(iObjAndHandle[i].iObject, (TUint32)RObjectIx::EReserved); sl@0: if (r<0) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iHandle = r; sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: sl@0: TInt toRemove=Random(iSeed)%(myIx.ActiveCount()+1); sl@0: TInt toAdd=toRemove; // will put them all back again... sl@0: while (toRemove--) sl@0: { sl@0: i=Random(iSeed)%aSize; sl@0: while (!iObjAndHandle[i].iObject) i=(i+1)%aSize; //Find the next non-NULL pointer sl@0: sl@0: TUint32 attr = 0; // Receives the attributes of the removed handle... sl@0: sl@0: if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: if ((attr & RObjectIx::EReserved) == 0) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return KErrBadHandle; sl@0: } sl@0: iObjAndHandle[i].iObject->Close(NULL); sl@0: iObjAndHandle[i].iObject = NULL; sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: sl@0: while (toAdd--) sl@0: { sl@0: i=Random(iSeed)%aSize; sl@0: while (iObjAndHandle[i].iObject) i=(i+1)%aSize; //Find the next NULL pointer sl@0: sl@0: if( (iObjAndHandle[i].iObject = new DObject) == NULL) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return KErrNoMemory; sl@0: } sl@0: iObjAndHandle[i].iObject->iContainerID = 0; sl@0: r = myIx.Add(iObjAndHandle[i].iObject, (TUint32)RObjectIx::EReserved); sl@0: if (r<0) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iHandle = r; sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: sl@0: for (i=aSize-1; i>=0; i--) //Remove in reverse sl@0: { sl@0: TUint32 attr = 0; // Receives the attributes of the removed handle... sl@0: sl@0: if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: if ((attr & RObjectIx::EReserved) == 0) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return KErrBadHandle; sl@0: } sl@0: iObjAndHandle[i].iObject->Close(NULL); sl@0: iObjAndHandle[i].iObject = NULL; sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: sl@0: return KErrNone; sl@0: } // DObjectTest::RObjectIxTest4 sl@0: sl@0: sl@0: // Adds a number of DObjects to RObjectIx using both normal and reserved slots, plus sl@0: // unused reserved slots then removes sl@0: // them in the same order. Repeat using the reverse order. Used in concurrent sl@0: // testing with multiple threads. sl@0: TInt DObjectTest::RObjectIxTestExerciseIx(RObjectIx& aObjectIx, TInt aSize) sl@0: { sl@0: TInt i,r; sl@0: DObject* object; sl@0: sl@0: aObjectIx.Check(0); sl@0: sl@0: for (i=0; iiContainerID = 0; sl@0: r = aObjectIx.Add(iObjAndHandle[i].iObject, i&0x1 ? (TUint32)RObjectIx::EReserved : 0); sl@0: if (r<0) sl@0: { sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iHandle = r; sl@0: } sl@0: sl@0: //---Test data consistency--- sl@0: for (i=0;iClose(NULL); sl@0: iObjAndHandle[i].iObject = NULL; sl@0: } sl@0: sl@0: aObjectIx.Check(0); sl@0: sl@0: for (i=0; iiContainerID = 0; sl@0: r = aObjectIx.Add(iObjAndHandle[i].iObject, i&0x1 ? (TUint32)RObjectIx::EReserved : 0); sl@0: if (r<0) sl@0: { sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iHandle = r; sl@0: } sl@0: sl@0: //---Test data consistency--- sl@0: for (i=0;i=0; i--) //Remove in reverse sl@0: { sl@0: TUint32 attr = 0; // Receives the attributes of the removed handle... sl@0: if (KErrNone != (r=aObjectIx.Remove(iObjAndHandle[i].iHandle, object, attr))) sl@0: { sl@0: return r; sl@0: } sl@0: if ((i&0x1) && ((attr & RObjectIx::EReserved) == 0)) sl@0: { sl@0: return KErrBadHandle; sl@0: } sl@0: sl@0: iObjAndHandle[i].iObject->Close(NULL); sl@0: sl@0: aObjectIx.Reserve(-1); // Remove a reserved object causing a TidyAndCompact()... sl@0: } sl@0: sl@0: aObjectIx.Check(0); sl@0: sl@0: return KErrNone; sl@0: } // DObjectTest::RObjectIxTestExerciseIx sl@0: sl@0: sl@0: /** sl@0: * Adds a number of DObjects to RObjectIx, tries random invalid handle to access them, sl@0: * then attempts removes them in the same order. sl@0: * sl@0: * @param aSize Size of handle array to use. sl@0: * sl@0: * @return KErrNone or standard error code. sl@0: */ sl@0: TInt DObjectTest::RObjectIxInvalidHandleLookupTest(TInt aSize) sl@0: { sl@0: TInt i, r; sl@0: DObject* object; sl@0: RObjectIx myIx; sl@0: sl@0: myIx.Check(0); sl@0: sl@0: // sl@0: // Add in some DObjects... sl@0: // sl@0: for (i = 0; i < aSize; i++) sl@0: { sl@0: if ((iObjAndHandle[i].iObject = new DObject) == NULL) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return KErrNoMemory; sl@0: } sl@0: sl@0: iObjAndHandle[i].iObject->iContainerID = 0; sl@0: sl@0: r = myIx.Add(iObjAndHandle[i].iObject, 0); sl@0: if (r < 0) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: iObjAndHandle[i].iHandle = r; sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: sl@0: // sl@0: // Randomly attempt to access handles... sl@0: // sl@0: TInt handlesToTest = aSize * KDObjectTestLoopCount; sl@0: TInt count; sl@0: sl@0: for (count = 0; count < handlesToTest; count++) sl@0: { sl@0: // sl@0: // A handle looks like this: sl@0: // Bits 0-14 index sl@0: // Bit 15 no-close flag (ignored) sl@0: // Bits 16-29 instance value sl@0: // Bit 30 thread local flag (ignored) sl@0: // Bit 31 special handle flag (should be 0) sl@0: // sl@0: NKern::LockSystem(); sl@0: TInt randomHandle = Kern::Random() & 0x3fff7fff; sl@0: TInt uniqueID = 0; // any object type! sl@0: sl@0: object = myIx.At(randomHandle, uniqueID); sl@0: NKern::UnlockSystem(); sl@0: sl@0: if (object != NULL) sl@0: { sl@0: // sl@0: // We've picked a valid handle, this is unlikely but check if sl@0: // it is really valid... sl@0: // sl@0: TBool found = EFalse; sl@0: sl@0: for (i = 0; i < aSize; i++) sl@0: { sl@0: if (iObjAndHandle[i].iHandle == randomHandle && sl@0: iObjAndHandle[i].iObject == object) sl@0: { sl@0: found = ETrue; sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (found == EFalse) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return KErrBadHandle; sl@0: } sl@0: } sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: sl@0: // sl@0: // Remove the DObjects... sl@0: // sl@0: for (i = 0; i < aSize; i++) sl@0: { sl@0: TUint32 attr = 0; // Receives the attributes of the removed handle... sl@0: sl@0: if (KErrNone != (r=myIx.Remove(iObjAndHandle[i].iHandle, object, attr))) sl@0: { sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: return r; sl@0: } sl@0: sl@0: iObjAndHandle[i].iObject->Close(NULL); sl@0: } sl@0: sl@0: myIx.Check(0); sl@0: myIx.Close(NULL); sl@0: sl@0: return KErrNone; sl@0: } // DObjectTest::RObjectIxInvalidHandleLookupTest sl@0: sl@0: sl@0: TInt DObjectTest::DObjectNameTest() sl@0: { sl@0: #define TEST_GOOD_NAME(name) if (Kern::ValidateName(name) != KErrNone) return KErrBadName; sl@0: #define TEST_BAD_NAME(name) if (Kern::ValidateName(name) != KErrBadName) return KErrBadName; sl@0: #define TEST_GOOD_FULLNAME(name) if (Kern::ValidateFullName(name) != KErrNone) return KErrBadName; sl@0: #define TEST_BAD_FULLNAME(name) if (Kern::ValidateFullName(name) != KErrBadName) return KErrBadName; sl@0: sl@0: sl@0: _LIT(KGoodName1,"DObject1 ABCDEFGHIJKLMNOPRSTUVWXYZ0123456789"); sl@0: _LIT(KGoodName2,"DObject2 abdefghijklmnoprstuvwxyz!\"#$%&'()+,-./;<=>@[\\]^_`{|}~"); sl@0: _LIT(KGoodFullName1,"DObject :3"); sl@0: _LIT(KBadName1,"DObject 5 *"); sl@0: _LIT(KBadName2,"DObject 6 ?"); sl@0: TUint8 badName3[] = {'D','O','b','j','e','c','t',0x00}; sl@0: TUint8 badName4[] = {'D','O','b','j','e','c','t',0x1f}; sl@0: TUint8 badName5[] = {'D','O','b','j','e','c','t',0x7f}; sl@0: TUint8 badName6[] = {'D','O','b','j','e','c','t',0xff}; sl@0: TPtr8 badNamePtr(badName3, sizeof(badName3), sizeof(badName3)); sl@0: sl@0: // Test Kern::ValidateName for good and bad names sl@0: TEST_GOOD_NAME(KGoodName1); sl@0: TEST_GOOD_NAME(KGoodName2); sl@0: TEST_BAD_NAME(KGoodFullName1); sl@0: TEST_BAD_NAME(KBadName1); sl@0: TEST_BAD_NAME(KBadName2); sl@0: TEST_BAD_NAME(badNamePtr); // already set to badName3 as no TPtr8 default constructor sl@0: badNamePtr.Set(badName4, sizeof(badName4), sizeof(badName4)); sl@0: TEST_BAD_NAME(badNamePtr); sl@0: badNamePtr.Set(badName5, sizeof(badName5), sizeof(badName5)); sl@0: TEST_BAD_NAME(badNamePtr); sl@0: badNamePtr.Set(badName6, sizeof(badName6), sizeof(badName6)); sl@0: TEST_BAD_NAME(badNamePtr); sl@0: sl@0: // Test Kern::ValidateFullName for good and bad full names sl@0: TEST_GOOD_FULLNAME(KGoodName1); sl@0: TEST_GOOD_FULLNAME(KGoodName2); sl@0: TEST_GOOD_FULLNAME(KGoodFullName1); sl@0: TEST_BAD_FULLNAME(KBadName1); sl@0: TEST_BAD_FULLNAME(KBadName2); sl@0: badNamePtr.Set(badName3, sizeof(badName3), sizeof(badName3)); sl@0: TEST_BAD_FULLNAME(badNamePtr); sl@0: badNamePtr.Set(badName4, sizeof(badName4), sizeof(badName4)); sl@0: TEST_BAD_FULLNAME(badNamePtr); sl@0: badNamePtr.Set(badName5, sizeof(badName5), sizeof(badName5)); sl@0: TEST_BAD_FULLNAME(badNamePtr); sl@0: badNamePtr.Set(badName6, sizeof(badName6), sizeof(badName6)); sl@0: TEST_BAD_FULLNAME(badNamePtr); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt DObjectTest::Request(TInt aFunction, TAny* a1, TAny* a2) sl@0: { sl@0: TInt r=KErrNone; sl@0: TInt i; sl@0: TInt duration; sl@0: SParam param; sl@0: TAny* args[2]; sl@0: sl@0: TRequestStatus* s=(TRequestStatus*)a1; sl@0: kumemget32(args,a2,sizeof(args)); sl@0: sl@0: switch (~aFunction) sl@0: { sl@0: case RTestDObject::ERObjectIxTest1: sl@0: duration = NKern::TickCount(); sl@0: sl@0: NKern::ThreadEnterCS(); sl@0: for (i = 1; i < KDObjectTestMaxTestSize; i = iduration, &duration, sizeof(TInt)); sl@0: sl@0: Kern::RequestComplete(s,KErrNone); sl@0: return KErrNone; sl@0: sl@0: case RTestDObject::ERObjectIxTest4: sl@0: duration = NKern::TickCount(); sl@0: sl@0: NKern::ThreadEnterCS(); sl@0: for (i = 1; i < KDObjectTestMaxTestSize; i = iCheck(0); sl@0: threadTestObjectIx->Close(NULL); sl@0: delete threadTestObjectIx; sl@0: threadTestObjectIx = NULL; sl@0: NKern::ThreadLeaveCS(); sl@0: sl@0: Kern::RequestComplete(s, KErrNone); sl@0: r = KErrNone; sl@0: } sl@0: break; sl@0: sl@0: case RTestDObject::ERObjectIxInvalidHandleLookupTest: sl@0: //RTestDObject::InvalidHandleLookupTest() sl@0: { sl@0: NKern::ThreadEnterCS(); sl@0: for (i = 1; i < KDObjectTestMaxTestSize; i = i