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 "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: // This file contains test classes and their implementations that test sl@0: // class CDefaultResolver. Demonstrates a simple set of derived class sl@0: // implementations using RTest. sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include "EComUidCodes.h" sl@0: #include "RegistryData.h" sl@0: #include "Registrar.h" sl@0: #include "RegistrarObserver.h" sl@0: #include "EComResolverParams.h" sl@0: #include "DefaultResolver.h" sl@0: #include "../EcomTestUtils/EcomTestUtils.h" sl@0: #include "DriveInfo.h" sl@0: #include "RegistryResolveTransaction.h" sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: // Used for suppressing warning in OOM tests sl@0: #define __UNUSED_VAR(var) var = var sl@0: sl@0: // Used for OOM test sl@0: #define TEST_OOM_ERR if(err == KErrNoMemory) User::Leave(err) sl@0: sl@0: // Interface Uids used within tests sl@0: const TUid KCExampleInterfaceUid = {0x10009DC0}; sl@0: const TUid KCExampleInterfaceImp = {0x10009DC1}; sl@0: const TInt KOneSecond = 1000000; sl@0: sl@0: // Interface Implementation Uids used for testing sl@0: const TInt KUidImplementation1 = 0x10009DC3; sl@0: const TInt KUidImplementation2 = 0x10009DC4; sl@0: sl@0: // Dlls copied to RAM for testing purpose sl@0: _LIT(KEComExDllOnZ, "z:\\RAMOnly\\EComExample5.dll"); sl@0: sl@0: // Contains .rsc files of dlls that be copied to RAM sl@0: // for testing purpose sl@0: _LIT(KEComExDllOnC, "c:\\sys\\bin\\EComExample5.dll"); sl@0: _LIT(KEComRscFileOnZ, "z:\\RAMOnly\\EComExample5.rsc"); sl@0: _LIT(KEComRscFileOnC, "c:\\resource\\plugins\\EComExample5.rsc"); sl@0: sl@0: _LIT(KEComExampleDllOnC, "C:\\sys\\bin\\EComExample.dll"); sl@0: _LIT(KEComExample2DllOnC, "C:\\sys\\bin\\EComExample2.dll"); sl@0: _LIT(KEComExample3DllOnC, "C:\\sys\\bin\\EComExample3.dll"); sl@0: sl@0: _LIT(KEComExampleRscOnC, "C:\\resource\\plugins\\EComExample.rsc"); sl@0: _LIT(KEComExample2RscOnC, "C:\\resource\\plugins\\EComExample2.rsc"); sl@0: _LIT(KEComExample3RscOnC, "C:\\resource\\plugins\\EComExample3.rsc"); sl@0: sl@0: _LIT(KEComExampleRscOnZ, "Z:\\RAMOnly\\EComExample.rsc"); sl@0: _LIT(KEComExample2RscOnZ, "Z:\\RAMOnly\\EComExample2.rsc"); sl@0: _LIT(KEComExample3RscOnZ, "Z:\\RAMOnly\\EComExample3.rsc"); sl@0: sl@0: sl@0: _LIT(KEComExampleDllOnZ, "Z:\\RAMOnly\\EComExample.dll"); sl@0: _LIT(KEComExample2DllOnZ, "Z:\\RAMOnly\\EComExample2.dll"); sl@0: _LIT(KEComExample3DllOnZ, "Z:\\RAMOnly\\EComExample3.dll"); sl@0: sl@0: // Datatype on implementations that .rsc file contains sl@0: _LIT8(KResolveMatchType, "text/wml"); sl@0: // Datatype to look for sl@0: _LIT8(KResolveImplementationType, "text/wml||data"); sl@0: sl@0: LOCAL_D CTrapCleanup* TheTrapCleanup=NULL; sl@0: sl@0: LOCAL_D CActiveScheduler* TheActiveScheduler=NULL; sl@0: sl@0: LOCAL_D RFs TheFs; sl@0: sl@0: LOCAL_D RTest test(_L("t_resolver.exe")); sl@0: sl@0: //LOCAL_D TCapabilitySet dummycaps; sl@0: // Utility clean up function sl@0: LOCAL_C void CleanupEComPtrArray(TAny* aArray); sl@0: sl@0: /** sl@0: This friend class allows us to access private and protected members of production sl@0: code class CDefaultResolver sl@0: */ sl@0: class TDefaultResolver_StateAccessor sl@0: { sl@0: public: sl@0: //Auxiliary methods that provide access to private members sl@0: TBool Match(CDefaultResolver& aResolver, sl@0: const TDesC8& aImplementationType, sl@0: const TDesC8& aMatchType, sl@0: TBool aIsGeneric) const; sl@0: sl@0: TUid Resolve(CDefaultResolver& aResolver, sl@0: RImplInfoArray& aImplementationInfo, sl@0: const TEComResolverParams& aAdditionalParameters) const; sl@0: }; sl@0: sl@0: /** sl@0: Searches for a match of a data type on an implementation type. sl@0: Match returns ETrue if aMatchType is found within aImplementationType sl@0: @param aResolver resolver object on which implementations are matched sl@0: @param aImplementationType The implementation data type to search for a match sl@0: @param aMatchType Search data that identifies/matches to implementations sl@0: @param aIsGeneric ETrue if wildcard matching is allowed sl@0: @return TBool ETrue if a match is found, EFalse if match is not found sl@0: */ sl@0: TBool TDefaultResolver_StateAccessor::Match(CDefaultResolver& aResolver, sl@0: const TDesC8& aImplementationType, sl@0: const TDesC8& aMatchType, sl@0: TBool aIsGeneric) const sl@0: { sl@0: return aResolver.Match(aImplementationType, aMatchType, aIsGeneric); sl@0: } sl@0: sl@0: /** sl@0: Selects an appropriate implementation from a list of possibles sl@0: @param aResolver resolver object on which implementations are resolved sl@0: @param aImplementationInfo Information on the potential implementations sl@0: @param aAdditionalParameters The data to match against to determine the sl@0: implementation sl@0: @return The Uid of a suitable implementation sl@0: */ sl@0: TUid TDefaultResolver_StateAccessor::Resolve(CDefaultResolver& aResolver, sl@0: RImplInfoArray& aImplementationInfo, sl@0: const TEComResolverParams& aAdditionalParameters) const sl@0: { sl@0: return aResolver.Resolve(aImplementationInfo, aAdditionalParameters); sl@0: } sl@0: sl@0: /** sl@0: The implementation of the abstract Registrar Observer class, sl@0: used for recieving notifications of registry changes. sl@0: Stub class(for CEComServer) used for the creation of CRegistrar class object. sl@0: CEComServer class acts as observer for CRegistrar. sl@0: */ sl@0: class CTestRegistrarObserver : public MRegistrarObserver // codescanner::missingcclass sl@0: { sl@0: public: sl@0: // This function is used by RegistrarObserver (i.e.CEComServer) to notify its sl@0: // clients(REComSession objects) that some change has happened in Registry. sl@0: // Here we have no clients to notify, so no implementaion. sl@0: void Notification( TInt /*aNotification*/ ) {} sl@0: }; sl@0: sl@0: /** sl@0: Test class encloses necessary members that aid to test CDefaultResolver sl@0: */ sl@0: class CResolverTest: public CBase sl@0: { sl@0: public: sl@0: static CResolverTest* NewL(); sl@0: virtual ~CResolverTest(); sl@0: sl@0: void IdentifyImplementationTestL(); sl@0: void ListAllTestL(); sl@0: void MatchTest(); sl@0: void ResolveTestL(); sl@0: sl@0: private: sl@0: CResolverTest(); sl@0: void ConstructL(); sl@0: sl@0: public: sl@0: /** The instance of the class under test */ sl@0: CDefaultResolver* iDefaultResolver; sl@0: /** The data store which is used by the resolver */ sl@0: CRegistryData* iRegistryData; sl@0: /** Friend class pointer used for accessing private members */ sl@0: TDefaultResolver_StateAccessor* iStateAccessor; sl@0: /** An array of potential implementations to resolve between */ sl@0: RImplInfoArray iImplementationData; sl@0: /** ECom example interface Uid */ sl@0: TUid iInterfaceUid; sl@0: /** The Uid returned by IdentifyImplementationL(), used to resolve sl@0: the implementation. */ sl@0: TUid iResolvedImpUid; sl@0: /** Additional parameters used for resolving between implementations */ sl@0: TEComResolverParams iAdditionalParameters; sl@0: /** CRegistrar */ sl@0: CRegistrar* iRegistrar; sl@0: /** Registrar observer test class */ sl@0: CTestRegistrarObserver* iRegistrarObserver; sl@0: /** CRegistryResolveTransaction */ sl@0: CRegistryResolveTransaction* iRegistryResolveTransaction; sl@0: /** ExtendedInterfaces List*/ sl@0: RArray iExtendedInterfaces; sl@0: /** Client Request*/ sl@0: TClientRequest iClientReq; sl@0: }; sl@0: sl@0: /** sl@0: Create a CResolverTest object on the CleanupStack sl@0: @return A pointer to the newly created class. sl@0: */ sl@0: CResolverTest* CResolverTest::NewL() sl@0: { sl@0: CResolverTest* self = new (ELeave) CResolverTest(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: /** sl@0: Standardized default constructor sl@0: @post CRegistrarTest is fully constructed. sl@0: */ sl@0: CResolverTest::CResolverTest() sl@0: : CBase() sl@0: { sl@0: // Interface uid to find implemenations sl@0: iInterfaceUid.iUid = KCExampleInterfaceUid.iUid; sl@0: } sl@0: sl@0: /** sl@0: Standardized 2nd(Initialization) phase of two phase construction. sl@0: Completes the safe construction of the CResolverTest object sl@0: @post CRegistrarTest is fully constructed. sl@0: @leave KErrNoMemory. sl@0: */ sl@0: void CResolverTest::ConstructL() sl@0: { sl@0: iStateAccessor = new(ELeave) TDefaultResolver_StateAccessor; sl@0: iRegistryData = CRegistryData::NewL(TheFs); sl@0: iRegistrarObserver=new (ELeave) CTestRegistrarObserver; sl@0: // construct the registry resolve transaction object here sl@0: TBool capability= ETrue; sl@0: iRegistryResolveTransaction = CRegistryResolveTransaction::NewL(*iRegistryData,iExtendedInterfaces,iClientReq,capability); sl@0: iRegistrar=CRegistrar::NewL(*iRegistryData, *iRegistrarObserver, TheFs); sl@0: iRegistrar->ProcessSSAEventL(EStartupStateNonCritical); sl@0: // next the default resolver sl@0: iDefaultResolver = CDefaultResolver::NewL(*iRegistryResolveTransaction); sl@0: } sl@0: sl@0: /** sl@0: Standardized default destructor sl@0: @post This object is properly destroyed. sl@0: */ sl@0: CResolverTest::~CResolverTest() sl@0: { sl@0: delete iStateAccessor; sl@0: delete iDefaultResolver; sl@0: delete iRegistrar; sl@0: delete iRegistrarObserver; sl@0: delete iRegistryData; sl@0: delete iRegistryResolveTransaction; sl@0: iExtendedInterfaces.Close(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-0659 sl@0: @SYMTestCaseDesc Create and delete Resolver object test sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates and deletes the resolver object sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void CreateDeleteTestL() sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0659 CreateDeleteTestL ")); sl@0: // sl@0: // Creates and deletes resolver object sl@0: // ------------------------------------------------------------------ sl@0: // sl@0: // Set up for heap leak checking sl@0: __UHEAP_MARK; sl@0: // and leaking thread handles sl@0: TInt startProcessHandleCount; sl@0: TInt startThreadHandleCount; sl@0: TInt endProcessHandleCount; sl@0: TInt endThreadHandleCount; sl@0: sl@0: // Test Starts... sl@0: RThread().HandleCount(startProcessHandleCount, startThreadHandleCount); sl@0: sl@0: CResolverTest* theTest=NULL; sl@0: sl@0: TRAPD(err, theTest = CResolverTest::NewL()); sl@0: test(err == KErrNone); sl@0: delete theTest; sl@0: sl@0: // Check for open handles sl@0: RThread().HandleCount(endProcessHandleCount, endThreadHandleCount); sl@0: test(startThreadHandleCount == endThreadHandleCount); sl@0: sl@0: // Test Ends... sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-1324 sl@0: @SYMTestCaseDesc Tests for CDefaultResolver::IdentifyImplementationL() function sl@0: @SYMTestPriority High sl@0: @SYMTestActions Tests that the resolver identifies most appropriate sl@0: interface implementation sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: void CResolverTest::IdentifyImplementationTestL() sl@0: { sl@0: // Tests that the resolver identifies most appropriate sl@0: // interface implementation sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1324 ")); sl@0: iAdditionalParameters.SetDataType(KResolveMatchType); sl@0: iAdditionalParameters.SetGenericMatch(ETrue);//Allow wildcard matching sl@0: TRAPD(err, iResolvedImpUid = sl@0: iDefaultResolver->IdentifyImplementationL(iInterfaceUid, iAdditionalParameters)); sl@0: TEST_OOM_ERR; sl@0: test(err == KErrNone); sl@0: // Check the Appropriate implementation id that should be identified sl@0: test(iResolvedImpUid.iUid == KUidImplementation1); sl@0: sl@0: test.Printf(_L("Interface Uid 0x%08x\n"), iInterfaceUid); sl@0: test.Printf(_L("Resolved Implementation Uid = 0x%08x\n"), iResolvedImpUid); sl@0: sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-1325 sl@0: @SYMTestCaseDesc Tests for CDefaultResolver::ListAllL() function sl@0: @SYMTestPriority High sl@0: @SYMTestActions The test executes by sending an interface id and data type to match. sl@0: Prints all the implementation for the interface id sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: void CResolverTest::ListAllTestL() sl@0: { sl@0: // Tests that ListAll() lists implementations for a specified interface sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1325 ")); sl@0: sl@0: // set datatype to text/wml and enable wildcard match sl@0: iAdditionalParameters.SetDataType(KResolveMatchType); sl@0: iAdditionalParameters.SetGenericMatch(ETrue); sl@0: RImplInfoArray* implData=NULL; sl@0: sl@0: /* This should list two implementations given below sl@0: depending on additional parameter and wildcard match sl@0: 10009DC3 Ver 2/"text/ wml"/10009DB3 sl@0: 10009DC4 Ver 2/"text/ *"/10009DB3 sl@0: */ sl@0: TRAPD(err, implData = iDefaultResolver->ListAllL(iInterfaceUid, iAdditionalParameters)); sl@0: sl@0: TEST_OOM_ERR; sl@0: test(err == KErrNone); sl@0: CleanupStack::PushL(TCleanupItem(CleanupEComPtrArray, implData)); sl@0: sl@0: const TInt availCount = implData->Count(); sl@0: test(availCount == 2); sl@0: sl@0: test.Printf(_L("Found %d implementations.\n"),availCount); sl@0: sl@0: for (TInt count=0;countDrive().Name(); sl@0: test.Printf(_L("%d. uid={%x} version=%d on drive %S\n"), count+1, sl@0: info->ImplementationUid(), info->Version(), &driveName); sl@0: sl@0: switch(info->ImplementationUid().iUid) sl@0: { sl@0: case KUidImplementation1: sl@0: test(info->Version()==2); sl@0: test(info->Drive()==EDriveC); sl@0: break; sl@0: sl@0: case KUidImplementation2: sl@0: test(info->Version()==2); sl@0: test(info->Drive()==EDriveC); sl@0: break; sl@0: sl@0: default: sl@0: test.Printf(_L("Mismatched implementation Uid\n")); sl@0: test(EFalse); sl@0: } sl@0: } sl@0: // Empty the array of implementations sl@0: CleanupStack::PopAndDestroy();//ifArray, results in a call to CleanupEComPtrArray sl@0: sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-1326 sl@0: @SYMTestCaseDesc Tests for TDefaultResolver_StateAccessor::Match() function sl@0: @SYMTestPriority High sl@0: @SYMTestActions The test executes by searching for a match of a data type on an implementation type sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: void CResolverTest::MatchTest() sl@0: { sl@0: // 1.Search using search parameters that result in a Match to a particular sl@0: // Implementation. sl@0: // 2.Search using search parameters that result in a mismatch. sl@0: // 3.Finally, search using search parameters with wildcards that result in a Match sl@0: sl@0: // Searches for KResolveMatchType (text/wml) on implementations sl@0: // KResolveImplementationType(text/wml||data) sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1326 ")); sl@0: TBool matchResult = iStateAccessor->Match(*iDefaultResolver, sl@0: KResolveImplementationType, sl@0: KResolveMatchType, sl@0: EFalse); sl@0: test(matchResult); sl@0: sl@0: _LIT8(KUnResolveableImplType, "Abc||xyz"); sl@0: // Pass data "Abc||xyz" which is not present on implementation type sl@0: // to look for and test for failure sl@0: matchResult = iStateAccessor->Match(*iDefaultResolver, sl@0: KUnResolveableImplType, sl@0: KResolveMatchType, sl@0: EFalse); sl@0: test(!matchResult); sl@0: sl@0: // Wild card in data type sl@0: _LIT8(KResolveWildImplType, "text*||xyz"); sl@0: sl@0: // Set to enable wild card search and test for success sl@0: matchResult = iStateAccessor->Match(*iDefaultResolver, sl@0: KResolveWildImplType, sl@0: KResolveMatchType, sl@0: ETrue); sl@0: test(matchResult); sl@0: sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-1327 sl@0: @SYMTestCaseDesc Tests the TDefaultResolver_StateAccessor::Resolve() function sl@0: @SYMTestPriority High sl@0: @SYMTestActions The test executes by sending an implementation data with additional parameter sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: void CResolverTest::ResolveTestL() sl@0: { sl@0: // Resolves a appropriate implementation from a list of possibles sl@0: sl@0: // Create iImplementationType on heap so that address can be passed to sl@0: // CImplementationInformation::NewL method sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1327 ")); sl@0: HBufC8* implementationType = HBufC8::NewL(KResolveImplementationType().Length()); sl@0: CleanupStack::PushL(implementationType); sl@0: TPtr8 impPtr = implementationType->Des(); sl@0: impPtr = KResolveImplementationType; sl@0: sl@0: // Interface Uid to create an item of implementation data sl@0: iResolvedImpUid.iUid=KCExampleInterfaceImp.iUid; sl@0: sl@0: TDriveUnit drive(EDriveC); sl@0: CImplementationInformation* impData = CImplementationInformation::NewL(iResolvedImpUid, sl@0: 0, sl@0: NULL, sl@0: implementationType, sl@0: NULL, sl@0: drive, sl@0: EFalse, sl@0: EFalse); sl@0: // Pop now before pushing impData since ownership is not with it sl@0: CleanupStack::Pop(implementationType); sl@0: CleanupStack::PushL(impData); sl@0: // Add implementation data so that you can resolve the same sl@0: User::LeaveIfError(iImplementationData.Append(impData)); sl@0: CleanupStack::Pop(impData); sl@0: sl@0: // set datatype to text/wml and enable wildcard match sl@0: iAdditionalParameters.SetDataType(KResolveMatchType); sl@0: iAdditionalParameters.SetGenericMatch(ETrue); sl@0: sl@0: // Newly resolved id sl@0: TUid resolvedUid; sl@0: TRAPD(err, resolvedUid = iStateAccessor->Resolve(*iDefaultResolver, sl@0: iImplementationData, sl@0: iAdditionalParameters)); sl@0: TEST_OOM_ERR; sl@0: test(err == KErrNone); sl@0: // confirm newly created interface id sl@0: test(resolvedUid == iResolvedImpUid); sl@0: sl@0: // Logging and cleaning up the array elements sl@0: while(iImplementationData.Count()) sl@0: { sl@0: // Fetch the address at first location and empty it sl@0: CImplementationInformation* impInfo = iImplementationData[0]; sl@0: test.Printf(_L("Resolved Uid is 0x%x \n"), impInfo->ImplementationUid()); sl@0: iImplementationData.Remove(0); sl@0: delete impInfo; sl@0: } sl@0: iImplementationData.Reset(); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-0660 sl@0: @SYMTestCaseDesc Tests for OOM while create and delete test sl@0: @SYMTestPriority High sl@0: @SYMTestActions Calls the CResolverTest test function sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: LOCAL_C void OOMCreateDeleteTest() sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0660 OOM CreateDeleteTest")); sl@0: TInt err; sl@0: TInt failAt = 1; sl@0: __UNUSED_VAR(failAt); sl@0: sl@0: CResolverTest* resolverTest = NULL; sl@0: sl@0: do sl@0: { sl@0: __UHEAP_MARK; sl@0: // find out the number of open handles sl@0: TInt startProcessHandleCount; sl@0: TInt startThreadHandleCount; sl@0: RThread().HandleCount(startProcessHandleCount, startThreadHandleCount); sl@0: sl@0: __UHEAP_SETFAIL(RHeap::EDeterministic, failAt+=100); sl@0: sl@0: TRAP(err, resolverTest = CResolverTest::NewL()); sl@0: sl@0: __UHEAP_SETFAIL(RHeap::ENone, 0); sl@0: sl@0: delete resolverTest; sl@0: resolverTest = NULL; sl@0: sl@0: // check that no handles have leaked sl@0: TInt endProcessHandleCount; sl@0: TInt endThreadHandleCount; sl@0: RThread().HandleCount(endProcessHandleCount, endThreadHandleCount); sl@0: sl@0: test(startProcessHandleCount == endProcessHandleCount); sl@0: test(startThreadHandleCount == endThreadHandleCount); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: while(err == KErrNoMemory); sl@0: sl@0: test.Printf(_L("- Succeeded at heap failure rate of %i\n"), failAt); sl@0: test(err == KErrNone); sl@0: } sl@0: sl@0: // Type definition for pointer to member function. sl@0: // Used in calling the CResolverTest member function for testing. sl@0: typedef void (CResolverTest::*ClassFuncPtrL) (void); sl@0: sl@0: /** sl@0: This function is used to force a discovery prior to the tests commencing. sl@0: */ sl@0: LOCAL_C void ForceDiscovery() sl@0: { sl@0: CTestRegistrarObserver* registrarObserver = new (ELeave) CTestRegistrarObserver; sl@0: CleanupStack::PushL(registrarObserver); sl@0: CRegistryData* registryData = CRegistryData::NewL(TheFs); sl@0: CleanupStack::PushL(registryData); sl@0: CRegistrar* registrar = CRegistrar::NewL(*registryData, *registrarObserver, TheFs); sl@0: CleanupStack::PushL(registrar); sl@0: registrar->ProcessSSAEventL(EStartupStateNonCritical); sl@0: sl@0: CleanupStack::PopAndDestroy(registrar); sl@0: CleanupStack::PopAndDestroy(registryData); sl@0: CleanupStack::PopAndDestroy(registrarObserver); sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-0661 sl@0: @SYMTestCaseDesc Wrapper function which calls other test functions sl@0: @SYMTestPriority High sl@0: @SYMTestActions Calls the CResolverTest test function sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: /** sl@0: Wrapper function to call all test functions sl@0: sl@0: @param testFunc pointer to test function sl@0: @param aTestDesc test function name sl@0: */ sl@0: LOCAL_C void DoBasicTestL(ClassFuncPtrL testFuncL, const TDesC& aTestDesc) sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0661 ")); sl@0: test.Next(aTestDesc); sl@0: sl@0: __UHEAP_MARK; sl@0: // find out the number of open handles sl@0: TInt startProcessHandleCount; sl@0: TInt startThreadHandleCount; sl@0: RThread().HandleCount(startProcessHandleCount, startThreadHandleCount); sl@0: sl@0: CResolverTest* resolverTest = CResolverTest::NewL(); sl@0: CleanupStack::PushL(resolverTest); sl@0: sl@0: (resolverTest->*testFuncL)(); sl@0: sl@0: CleanupStack::PopAndDestroy(resolverTest); sl@0: sl@0: // check that no handles have leaked sl@0: TInt endProcessHandleCount; sl@0: TInt endThreadHandleCount; sl@0: RThread().HandleCount(endProcessHandleCount, endThreadHandleCount); sl@0: sl@0: test(startProcessHandleCount == endProcessHandleCount); sl@0: test(startThreadHandleCount == endThreadHandleCount); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-0662 sl@0: @SYMTestCaseDesc Function to call all OOM test functions sl@0: @SYMTestPriority High sl@0: @SYMTestActions Calls the CResolverTest test function sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ0000 sl@0: */ sl@0: /** sl@0: Wrapper function to call all OOM test functions sl@0: sl@0: @param testFuncL pointer to OOM test function sl@0: @param aTestDesc test function name sl@0: */ sl@0: LOCAL_C void DoOOMTestL(ClassFuncPtrL testFuncL, const TDesC& aTestDesc) sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0662 ")); sl@0: test.Next(aTestDesc); sl@0: sl@0: TInt err; sl@0: TInt tryCount = 0; sl@0: do sl@0: { sl@0: __UHEAP_MARK; sl@0: // find out the number of open handles sl@0: TInt startProcessHandleCount; sl@0: TInt startThreadHandleCount; sl@0: RThread().HandleCount(startProcessHandleCount, startThreadHandleCount); sl@0: sl@0: CResolverTest* resolverTest = CResolverTest::NewL(); sl@0: CleanupStack::PushL(resolverTest); sl@0: sl@0: __UHEAP_SETFAIL(RHeap::EDeterministic, ++tryCount); sl@0: sl@0: TRAP(err, (resolverTest->*testFuncL)()); sl@0: sl@0: __UHEAP_SETFAIL(RHeap::ENone, 0); sl@0: sl@0: CleanupStack::PopAndDestroy(resolverTest); sl@0: resolverTest = NULL; sl@0: // check that no handles have leaked sl@0: TInt endProcessHandleCount; sl@0: TInt endThreadHandleCount; sl@0: RThread().HandleCount(endProcessHandleCount, endThreadHandleCount); sl@0: sl@0: test(startProcessHandleCount == endProcessHandleCount); sl@0: test(startThreadHandleCount == endThreadHandleCount); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } while(err == KErrNoMemory); sl@0: sl@0: test(err == KErrNone); sl@0: test.Printf(_L("- server succeeded at heap failure rate of %i\n"), tryCount); sl@0: } sl@0: sl@0: LOCAL_C void DoTestsL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: // Force a discovery to ensure that the ecom.dat file is updated with the data from the plugins sl@0: // required for this test. The plugins for this test are copied by calling CopyPlugins() from E32Main(). sl@0: // They are deleted by calling DeleteTestPlugin() also from E32Main(). sl@0: ForceDiscovery(); sl@0: sl@0: // Basic tests sl@0: CreateDeleteTestL(); sl@0: DoBasicTestL(&CResolverTest::IdentifyImplementationTestL, _L("Identify implementation test")); sl@0: DoBasicTestL(&CResolverTest::ListAllTestL, _L("ListAllTestL")); sl@0: DoBasicTestL(&CResolverTest::MatchTest, _L("MatchTest")); sl@0: DoBasicTestL(&CResolverTest::ResolveTestL, _L("ResolveTestL")); sl@0: sl@0: // OOM tests sl@0: OOMCreateDeleteTest(); sl@0: DoOOMTestL(&CResolverTest::IdentifyImplementationTestL, _L("OOM IdentifyImplementationTestL")); sl@0: DoOOMTestL(&CResolverTest::ListAllTestL, _L("OOM ListAllTestL")); sl@0: DoOOMTestL(&CResolverTest::MatchTest, _L("OOM MatchTest")); sl@0: DoOOMTestL(&CResolverTest::ResolveTestL, _L("OOM ResolveTestL")); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: This function is used for cleanup support of locally declared arrays sl@0: */ sl@0: LOCAL_C void CleanupEComPtrArray(TAny* aArray) sl@0: { sl@0: sl@0: (static_cast(aArray))->Reset(); sl@0: delete aArray;// delete here sl@0: sl@0: } sl@0: sl@0: /** sl@0: Copies the Plugins to specific folder for testing purpose sl@0: */ sl@0: LOCAL_C void CopyPlugins() sl@0: { sl@0: // Copy the dlls and .rsc files on to RAM sl@0: TRAPD(err, EComTestUtils::FileManCopyFileL(KEComExDllOnZ, KEComExDllOnC)); sl@0: test(err==KErrNone); sl@0: sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComRscFileOnZ, KEComRscFileOnC)); sl@0: test(err==KErrNone); sl@0: sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComExampleDllOnZ, KEComExampleDllOnC)); sl@0: test(err==KErrNone); sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample2DllOnZ, KEComExample2DllOnC)); sl@0: test(err==KErrNone); sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample3DllOnZ, KEComExample3DllOnC)); sl@0: test(err==KErrNone); sl@0: sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComExampleRscOnZ, KEComExampleRscOnC)); sl@0: test(err==KErrNone); sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample2RscOnZ, KEComExample2RscOnC)); sl@0: test(err==KErrNone); sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample3RscOnZ, KEComExample3RscOnC)); sl@0: test(err==KErrNone); sl@0: } sl@0: sl@0: // Deleting plugin from the RAM for cleanup purpose sl@0: inline LOCAL_C void DeleteTestPlugin() sl@0: { sl@0: TRAPD(err, EComTestUtils::FileManDeleteFileL(KEComExDllOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComRscFileOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExampleDllOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample2DllOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample3DllOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExampleRscOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample2RscOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample3RscOnC)); sl@0: } sl@0: sl@0: //Initialise the Active Scheduler sl@0: LOCAL_C void SetupL() sl@0: { sl@0: // Construct and install the Active Scheduler. The Active Schedular is needed sl@0: // by components used by this test as they are ActiveObjects. sl@0: TheActiveScheduler = new(ELeave)CActiveScheduler; sl@0: CActiveScheduler::Install(TheActiveScheduler); sl@0: } sl@0: sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: test.Printf(_L("\n")); sl@0: test.Title(); sl@0: test.Start(_L("Resolver Tests")); sl@0: sl@0: TheTrapCleanup = CTrapCleanup::New(); sl@0: sl@0: TRAPD(err, SetupL()); sl@0: test(err == KErrNone); sl@0: sl@0: // Connect the file server instance sl@0: User::LeaveIfError(TheFs.Connect()); sl@0: sl@0: CopyPlugins(); sl@0: sl@0: // Wait, so that ECom server looks for plugins copied from Z: to C drive sl@0: // ECOM server could be already started. It means that when we copy some sl@0: // ECOM plugins from Z: to C: drive - ECOM server should look for and sl@0: // find the new ECOM plugins. The ECOM server uses for that CDiscoverer::CIdleScanningTimer sl@0: // which is an active object. So the discovering service is asynchronous. We have to sl@0: // wait some time until it finishes. Otherwise ListImplementationsL could fail to find sl@0: // requested implementations. sl@0: User::After(KOneSecond * 3); sl@0: sl@0: TRAP(err, DoTestsL()); sl@0: test(err == KErrNone); sl@0: sl@0: // Cleanup files. If the cleanup fails that is no problem, sl@0: // as any subsequent tests will replace them. The only downside sl@0: // would be the disk not being tidied sl@0: DeleteTestPlugin(); sl@0: sl@0: TheFs.Close(); sl@0: delete TheTrapCleanup; sl@0: delete TheActiveScheduler; sl@0: test.End(); sl@0: test.Close(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: return(KErrNone); sl@0: }