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: // Contains tests with invalid/missing plugin DLLs sl@0: // sl@0: // sl@0: sl@0: sl@0: #include sl@0: #include "EComUidCodes.h" sl@0: #include "Interface.h" // interface to Plugins sl@0: #include "../EcomTestUtils/EcomTestUtils.h" sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: LOCAL_D RTest test(_L("t_plugindiscovery.exe")); 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: // Implementaion ID used for testing sl@0: const TUid KUidTestImplementation = {0x101F847C}; sl@0: sl@0: sl@0: //It is used by some test methods which are called two times: sl@0: //from normal test and from OOM test. sl@0: static void LeaveIfErrNoMemory(TInt aError) sl@0: { sl@0: if(aError == KErrNoMemory) sl@0: { sl@0: REComSession::FinalClose(); sl@0: User::Leave(aError); sl@0: } sl@0: } sl@0: sl@0: sl@0: // Plugins used in tests. sl@0: _LIT(KEComInvalidDllOnZ, "z:\\RAMOnly\\InvalidSIDPlugin.dll"); sl@0: _LIT(KEComInvalidRscOnZ, "z:\\RAMOnly\\InvalidSIDPlugin.rsc"); sl@0: _LIT(KEComInvalidDllOnC, "c:\\sys\\bin\\InvalidSIDPlugin.dll"); sl@0: _LIT(KEComInvalidRscOnC, "c:\\resource\\plugins\\InvalidSIDPlugin.rsc"); sl@0: sl@0: _LIT(KEComExample5RscOnZ, "z:\\RAMOnly\\EComExample5.rsc"); sl@0: _LIT(KEComExample5RscOnC, "c:\\resource\\plugins\\EComExample5.rsc"); sl@0: _LIT(KEComRomRslvrExampleRscOnCRomLocation, "z:\\RAMOnly\\EComRomRslvrExampleOnC.RSC"); sl@0: _LIT(KEComRomRslvrExampleRscOnCRamLocation, "c:\\resource\\plugins\\EComRomRslvrExampleOnZ.RSC"); sl@0: sl@0: // Plugins used in plugins directory removing test sl@0: _LIT(KEComDefectPluginDLLOnZ, "Z:\\RAMOnly\\DefectPlugin.dll"); sl@0: _LIT(KEComDefectPluginRSCOnZ, "Z:\\RAMOnly\\DefectPlugin.rsc"); sl@0: _LIT(KEComDefectPluginDLLOnC, "C:\\sys\\bin\\DefectPlugin.dll"); sl@0: _LIT(KEComDefectPluginRSCOnC, "C:\\Resource\\Plugins\\DefectPlugin.rsc"); sl@0: _LIT(KEComResourcePluginDirNameOnC, "C:\\Resource\\Plugins\\"); sl@0: _LIT(KEComResourcePluginDirNameOffOnC, "C:\\Resource\\PluginsNameOff\\"); sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-0030 sl@0: @SYMTestCaseDesc Test that an orphaned resource file does not create a registry sl@0: entry. sl@0: @SYMTestPriority High sl@0: @SYMTestActions EComExample5.rsc file copied to C: drive. sl@0: Check call to REComSession::CreateImplementationL() via test sl@0: CExampleInterface class fails to return the implementation. sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ3846 sl@0: */ sl@0: LOCAL_C void TestOrphanedRscFileL() sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0030 ")); sl@0: __UHEAP_MARK; sl@0: sl@0: // Copy plugin sl@0: TRAPD(ignoreErr, EComTestUtils::FileManDeleteFileL(KEComExample5RscOnC)); sl@0: ignoreErr = ignoreErr; sl@0: sl@0: TRAPD(err, EComTestUtils::FileManCopyFileL(KEComExample5RscOnZ, KEComExample5RscOnC)); sl@0: test(err == KErrNone); sl@0: sl@0: // The reason for the folowing delay is: 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 an active object, sl@0: // which scans plugin directories. So the discovering service is asynchronous. sl@0: // We have to wait some time until it finishes. sl@0: // Otherwise CreateImplementationsL could fail to create requested implementations. sl@0: WAIT_FOR3s; sl@0: sl@0: CExampleInterface* interfaceimpl = NULL; sl@0: TRAP(err, interfaceimpl = CExampleInterface::NewL2(KUidTestImplementation)); sl@0: ::LeaveIfErrNoMemory(err); sl@0: test(err == KErrNotFound); sl@0: CleanupStack::PushL(interfaceimpl); sl@0: sl@0: CleanupStack::PopAndDestroy(interfaceimpl); sl@0: REComSession::FinalClose(); sl@0: sl@0: // Delete plugin sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample5RscOnC)); sl@0: test(err == KErrNone); sl@0: __UHEAP_MARK; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-1404 sl@0: @SYMTestCaseDesc Test that an orphaned resource file does not create a registry entry. sl@0: and that other valid implementations are discovered instead. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Copy EComRomRslvrExampleOnC to the plug-ins directory on the C drive, without the associated DLL sl@0: Because the DLL is not there, Ecom should fall back to the implementations on the Z drive in EComRomRslvrExampleOnZ sl@0: @SYMTestExpectedResults ECom plugins with invalid DLLs fall back to the correct implementations. sl@0: @SYMPREQ PREQ1192 sl@0: */ sl@0: LOCAL_C void TestOrphanedRscFileFallBackL() sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1404 ")); sl@0: __UHEAP_MARK; sl@0: sl@0: // Copy plugin resource file and NOT the associated DLL sl@0: TRAPD(err, EComTestUtils::FileManCopyFileL(KEComRomRslvrExampleRscOnCRomLocation, KEComRomRslvrExampleRscOnCRamLocation)); sl@0: test(err == KErrNone); sl@0: sl@0: // The reason for the folowing delay is: 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 an active object, sl@0: // which scans plugin directories. So the discovering service is asynchronous. sl@0: // We have to wait some time until it finishes. sl@0: // Otherwise ListImplementationsL could fail to find requested implementations. sl@0: WAIT_FOR3s; sl@0: sl@0: TUid romRslvrExampleInterfaceUid = {0x10009DC8}; sl@0: RImplInfoPtrArray ifArray; sl@0: TRAP(err, REComSession::ListImplementationsL(romRslvrExampleInterfaceUid, ifArray)); sl@0: ::LeaveIfErrNoMemory(err); sl@0: test(err == KErrNone); sl@0: sl@0: // Go through the implementations for the given interface, and find the ones that match up with sl@0: // EComRomRslvrExampleRscOnZ (and not EComRomRslvrExampleRscOnC becuase it's DLL is missing) sl@0: // EComRomRslvrExampleOnZ contains the implementation 0x10009DC7v2 and 0x10009DC6v1 (these should be found) sl@0: // EComRomRslvrExampleOnC contains the implementation 0x10009DC7v1 and 0x10009DC6v2 (these should NOT be returned becuase of the missing DLL) sl@0: TBool foundRightImplementation1 = EFalse; sl@0: TBool foundRightImplementation2 = EFalse; sl@0: for(TInt index = 0; index < ifArray.Count(); ++index) sl@0: { sl@0: TUid uid = ifArray[index]->ImplementationUid(); sl@0: TInt version = ifArray[index]->Version(); sl@0: TInt drive = ifArray[index]->Drive(); sl@0: if (uid.iUid == 0x10009DC6) sl@0: { sl@0: test(version == 1); sl@0: test(drive==EDriveZ); sl@0: foundRightImplementation1 = ETrue; sl@0: } sl@0: if (uid.iUid == 0x10009DC7) sl@0: { sl@0: test(version == 2); sl@0: test(drive==EDriveZ); sl@0: foundRightImplementation2 = ETrue; sl@0: } sl@0: } sl@0: test(foundRightImplementation1 && foundRightImplementation2); sl@0: sl@0: ifArray.ResetAndDestroy(); sl@0: REComSession::FinalClose(); sl@0: sl@0: // Delete plugin sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComRomRslvrExampleRscOnCRamLocation)); sl@0: test(err == KErrNone); sl@0: __UHEAP_MARK; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-0031 sl@0: @SYMTestCaseDesc Test that a plugin whose SID does not match the value in it's sl@0: resource file will not be installed in the registry. sl@0: @SYMTestPriority High sl@0: @SYMTestActions InvalidSIDPlugin dll and rsc files copied to C: drive. sl@0: Verify plugin is not registered by checking sl@0: ListImplementationsL returns zero plugins for this interface. sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMREQ REQ3846 sl@0: */ sl@0: LOCAL_C void TestInvalidSIDPluginL() sl@0: { sl@0: // InvalidSIDPlugin .dll and .rsc are copied from EComExample5.dll and sl@0: // HeapTestImpl.rsc. sl@0: sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0031 ")); sl@0: __UHEAP_MARK; sl@0: sl@0: // Copy plugins sl@0: TRAPD(err, EComTestUtils::FileManCopyFileL(KEComInvalidDllOnZ, KEComInvalidDllOnC)); sl@0: test(err == KErrNone); sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComInvalidRscOnZ, KEComInvalidRscOnC)); sl@0: test(err == KErrNone); sl@0: sl@0: // The reason for the folowing delay is: 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 an active object, sl@0: // which scans plugin directories. So the discovering service is asynchronous. sl@0: // We have to wait some time until it finishes. sl@0: // Otherwise ListImplementationsL could fail to find requested implementations. sl@0: WAIT_FOR3s; sl@0: sl@0: TUid ifUid = {0x101FE392}; // HeapTestImpl.rsc interface_uid sl@0: RImplInfoPtrArray ifArray; sl@0: REComSession::ListImplementationsL(ifUid, ifArray); sl@0: sl@0: const TInt availCount = ifArray.Count(); sl@0: test.Printf(_L("Found %d implementations.\n"),availCount); sl@0: test(availCount == 0); sl@0: sl@0: ifArray.ResetAndDestroy(); sl@0: REComSession::FinalClose(); // Don't want leaks outside the test sl@0: sl@0: // Cleanup plugins sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComInvalidDllOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComInvalidRscOnC)); sl@0: sl@0: __UHEAP_MARK; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-ECOM-CT-1858 sl@0: @SYMTestCaseDesc Test that rediscovery of removing and adding "\Resource\Plugins" directory sl@0: works properly. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Removes "\Resource\Plugins" directory on C: drive, check that sl@0: rediscovery works properly by verifying plugin's registration. sl@0: Adds "\Resource\Plugins" directory on C: drive, check that rediscovery works sl@0: fine by verifying plugin's registration. sl@0: @SYMTestExpectedResults The test must not fail. sl@0: @SYMDEF DEF088454 sl@0: */ sl@0: LOCAL_C void TestPluginsDirectoryRemovingL() sl@0: { sl@0: test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1858 ")); sl@0: __UHEAP_MARK; sl@0: sl@0: /** sl@0: Add The following plugin to C drive sl@0: sl@0: Interface UID DLL UID Imp. UID Version DllFile sl@0: ------------------------------------------------------------------------------------------------------------------------------------------ sl@0: 0x102797A1 0x102797A0 0x102797A2 1 C:\\..\\DefectPlugin.dll sl@0: sl@0: **/ sl@0: TRAPD(err, EComTestUtils::FileManCopyFileL(KEComDefectPluginDLLOnZ, KEComDefectPluginDLLOnC)); sl@0: test(err == KErrNone); sl@0: TRAP(err, EComTestUtils::FileManCopyFileL(KEComDefectPluginRSCOnZ, KEComDefectPluginRSCOnC)); sl@0: test(err == KErrNone); sl@0: sl@0: WAIT_FOR3s; sl@0: sl@0: TUid interfaceUid={0x102797A1}; sl@0: RImplInfoPtrArray implArray; sl@0: sl@0: // Now start ecom discovery and get implementations for IF UID 0x102797A1 sl@0: TRAP(err, REComSession::ListImplementationsL(interfaceUid, implArray)); sl@0: ::LeaveIfErrNoMemory(err); sl@0: test(err == KErrNone); sl@0: sl@0: // Expected number of implementations returned sl@0: test(implArray.Count()==1); sl@0: sl@0: // Check that the implementation uid returned matched the specs above sl@0: TUid implUid = implArray[0]->ImplementationUid(); sl@0: TInt version = implArray[0]->Version(); sl@0: TInt drive = implArray[0]->Drive(); sl@0: // imp. uid sl@0: test(implUid.iUid == 0x102797A2); sl@0: // version sl@0: test(version == 1); sl@0: // C drive sl@0: test(drive == EDriveC); sl@0: sl@0: implArray.ResetAndDestroy(); sl@0: sl@0: // Now remove plugins directory sl@0: TRAP(err, EComTestUtils::FileManRenameL(KEComResourcePluginDirNameOnC, KEComResourcePluginDirNameOffOnC)); sl@0: test(err == KErrNone); sl@0: TRAP(err, EComTestUtils::FileManDeleteDirL(KEComResourcePluginDirNameOnC)); sl@0: test(err == KErrNone); sl@0: sl@0: TEntry entry; sl@0: err = TheFs.Entry(KEComResourcePluginDirNameOnC, entry); sl@0: // Test the plugins directory is now gone sl@0: test(err == KErrNotFound); sl@0: sl@0: // Wait EComServer performing rediscovery sl@0: WAIT_FOR3s; sl@0: sl@0: TRAP(err, REComSession::ListImplementationsL(interfaceUid, implArray)); sl@0: ::LeaveIfErrNoMemory(err); sl@0: test(err == KErrNone); sl@0: sl@0: // Test the rediscovery and directory scanning has been performed on renaming off event sl@0: test(implArray.Count()==0); sl@0: sl@0: implArray.ResetAndDestroy(); sl@0: sl@0: // Now rename plugins directory back sl@0: TRAP(err, EComTestUtils::FileManRenameL(KEComResourcePluginDirNameOffOnC, KEComResourcePluginDirNameOnC)); sl@0: test(err == KErrNone); sl@0: TRAP(err, EComTestUtils::FileManDeleteDirL(KEComResourcePluginDirNameOffOnC)); sl@0: test(err == KErrNone); sl@0: sl@0: // Test the plugins directory is added back sl@0: err = TheFs.Entry(KEComResourcePluginDirNameOnC, entry); sl@0: test(err == KErrNone); sl@0: sl@0: // Wait EComServer performing rediscovery sl@0: WAIT_FOR3s; sl@0: sl@0: TRAP(err, REComSession::ListImplementationsL(interfaceUid, implArray)); sl@0: ::LeaveIfErrNoMemory(err); sl@0: test(err == KErrNone); sl@0: sl@0: // Test the rediscovery and directory scanning has been performed on renaming off event sl@0: test(implArray.Count()==1); sl@0: sl@0: //Check that the implementation uid returned matched the specs above sl@0: implUid = implArray[0]->ImplementationUid(); sl@0: version = implArray[0]->Version(); sl@0: drive = implArray[0]->Drive(); sl@0: test(implUid.iUid == 0x102797A2); sl@0: test(version == 1); sl@0: test(drive == EDriveC); sl@0: sl@0: implArray.ResetAndDestroy(); sl@0: sl@0: REComSession::FinalClose(); // Don't want leaks outside the test sl@0: sl@0: // Cleanup plugins sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComDefectPluginDLLOnC)); sl@0: TRAP(err, EComTestUtils::FileManDeleteFileL(KEComDefectPluginRSCOnC)); sl@0: sl@0: __UHEAP_MARK; sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: typedef void (*ClassFuncPtrL) (void); sl@0: sl@0: /** sl@0: Wrapper function to call all test functions sl@0: sl@0: @param testFuncL 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(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: //Call the test function sl@0: (*testFuncL)(); 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(startThreadHandleCount == endThreadHandleCount); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: Wrapper function to call all OOM test functions 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(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: __UHEAP_SETFAIL(RHeap::EDeterministic, ++tryCount); sl@0: sl@0: //Call the test function sl@0: TRAP(err, ((*testFuncL)())); sl@0: sl@0: __UHEAP_SETFAIL(RHeap::ENone, 0); sl@0: sl@0: // release handles sl@0: if(err == KErrNone) sl@0: { sl@0: REComSession::FinalClose(); sl@0: } 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: } 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: sl@0: sl@0: LOCAL_C void DoTestsL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: // Basic tests sl@0: test.Next(_L("Basic Test Suite")); sl@0: test.Start(_L("Basic Test Suite")); sl@0: DoBasicTestL(&TestOrphanedRscFileL, _L("TestOrphanedRscFileL")); sl@0: DoBasicTestL(&TestInvalidSIDPluginL, _L("TestInvalidSIDPluginL")); sl@0: DoBasicTestL(&TestOrphanedRscFileFallBackL, _L("TestOrphanedRscFileFallBackL")); sl@0: DoBasicTestL(&TestPluginsDirectoryRemovingL, _L("TestPluginsDirectoryRemovingL")); sl@0: test.End(); sl@0: sl@0: // OOM tests sl@0: test.Next(_L("Out-of-memory Repeat Tests")); sl@0: test.Start(_L("Out-of-memory Repeat Tests")); sl@0: DoOOMTestL(&TestOrphanedRscFileL, _L("TestOrphanedRscFileL")); sl@0: DoOOMTestL(&TestInvalidSIDPluginL, _L("TestInvalidSIDPluginL")); sl@0: DoOOMTestL(&TestOrphanedRscFileFallBackL, _L("TestOrphanedRscFileFallBackL")); sl@0: DoOOMTestL(&TestPluginsDirectoryRemovingL, _L("TestPluginsDirectoryRemovingL")); sl@0: test.End(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: //Initialise the Active Scheduler sl@0: // 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: 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("Dual-Mode Discovery Tests")); sl@0: sl@0: TheTrapCleanup = CTrapCleanup::New(); sl@0: TInt err = TheFs.Connect(); sl@0: test(err == KErrNone); sl@0: TRAP(err, SetupL()); sl@0: test(err == KErrNone); sl@0: sl@0: sl@0: // Perform tests. sl@0: TRAP(err,DoTestsL()); sl@0: test(err==KErrNone); sl@0: sl@0: delete TheActiveScheduler; sl@0: TheFs.Close(); sl@0: delete TheTrapCleanup; sl@0: sl@0: test.End(); sl@0: test.Close(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: return (KErrNone); sl@0: }