diff -r 000000000000 -r e4d67989cc36 lowlevellibsandfws/pluginfw/Framework/SimpleTests/t_finalclose.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lowlevellibsandfws/pluginfw/Framework/SimpleTests/t_finalclose.cpp Tue Feb 02 02:01:42 2010 +0200 @@ -0,0 +1,593 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include +#include +#include +#include +#include "../EcomTestUtils/EcomTestUtils.h" +#include "LoadManager.h" +#include +#include "EComUidCodes.h" +#include "Interface.h" // interface to Plugins + +_LIT(KEComExDllOnC, "c:\\sys\\bin\\EComExample5.dll"); +_LIT(KEComRscFileOnZ, "z:\\RAMOnly\\EComExample5.rsc"); +_LIT(KEComRscFileOnC, "c:\\resource\\plugins\\EComExample5.rsc"); + +_LIT(KEComExampleDllOnC, "C:\\sys\\bin\\EComExample.dll"); +_LIT(KEComExample2DllOnC, "C:\\sys\\bin\\EComExample2.dll"); +_LIT(KEComExample3DllOnC, "C:\\sys\\bin\\EComExample3.dll"); + +_LIT(KEComExampleRscOnC, "C:\\resource\\plugins\\EComExample.rsc"); +_LIT(KEComExample2RscOnC, "C:\\resource\\plugins\\EComExample2.rsc"); +_LIT(KEComExample3RscOnC, "C:\\resource\\plugins\\EComExample3.rsc"); + +_LIT(KEComExampleRscOnZ, "Z:\\RAMOnly\\EComExample.rsc"); +_LIT(KEComExample2RscOnZ, "Z:\\RAMOnly\\EComExample2.rsc"); +_LIT(KEComExample3RscOnZ, "Z:\\RAMOnly\\EComExample3.rsc"); + + +_LIT(KEComExDllOnZ, "z:\\RAMOnly\\EComExample5.dll"); +_LIT(KEComExampleDllOnZ, "Z:\\RAMOnly\\EComExample.dll"); +_LIT(KEComExample2DllOnZ, "Z:\\RAMOnly\\EComExample2.dll"); +_LIT(KEComExample3DllOnZ, "Z:\\RAMOnly\\EComExample3.dll"); + +/** Test cases covered in this test code: +1. Thread create imp destroy then not calling FinalClose() will cause a panic inside the thread( capture this panic)(memory leak) + +2. Thread list implementation then not calling FinalClose() will cause a panic inside the thread(capture this panic)(memory leak). + +3. Thread Create Impl1, Create Impl2, Destroy Impl2, Destory Impl1 then FinalClose() no memory leak. + +4. Thread create Impl1, call FinalClose() 2x, Destroy Impl1 then FinalClose() to show that FinalClose() can be called many times with no unknown consequence. + +5. REComSession::public constructor (without OpenL), called FinalClose () 2x, then Close(), no problem and memory leak. + +6. REComSession::OpenL,call Close() then call FinalClose() to show no memory leak problem. + +7. Test calling REComSession::FinalClose() to show no memory leak, errors, crash problem +*/ + +LOCAL_D RTest test(_L("Final Close Test")); + +class RFinalCloseTest + { +public: + //Test case 1 + static TInt Create_Destroy_Without_FinalClose(TAny*); + static TInt Create_Destroy_With_FinalCloseL(); + static TInt Create_Destroy_TestL(); + + //Test case 2 + static TInt ListImpl_Without_FinalClose(TAny*); + static TInt ListImpl_With_FinalCloseL(); + static void ListImplementation_TestL(); + + //Test case 3 + static void Create_Destroy2_With_FinalCloseL(); + + //Test case 4 + static void Create_Destroy3_With_FinalCloseL(); + + //Test case 5 + static void Create_Destroy4_With_FinalCloseL(); + + //Test case 6 + static void FinalClose(); + + //Test case 7 + static void NonConstructL_Create_Destroy(); + + static void ThreadPanicTest(const TDesC& aName,TThreadFunction aFunction); + }; + +/** +Test creating an implementation, deleting the implementation +and then call FinalClose(). Check that there is no crash and memory leak + +@SYMTestCaseID SYSLIB-ECOM-CT-0759 +@SYMTestCaseDesc Tests for creating and destroying an implementation +@SYMTestPriority High +@SYMTestActions Create and delete a new implementation with UID and initialisation parameters. + Call up REComSession::FinalClose + Check for no crash and memory leaks. +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +TInt RFinalCloseTest::Create_Destroy_With_FinalCloseL() + { + __UHEAP_MARK; + + Create_Destroy_TestL(); + + REComSession::FinalClose(); + + __UHEAP_MARKEND; + return KErrNone; + } + +/** +Test creating an implementation, deleting the implementation +Never call FinalClose() to show memory leak panic + +@SYMTestCaseID SYSLIB-ECOM-CT-0760 +@SYMTestCaseDesc Tests for creating and destroying an implementation +@SYMTestPriority High +@SYMTestActions Create and delete a new implementation with UID and initialisation parameters. + FinalClose is omitted to show memory leak panic +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +TInt RFinalCloseTest::Create_Destroy_Without_FinalClose(TAny*) + { + + __UHEAP_MARK; + CTrapCleanup* threadcleanup = CTrapCleanup::New(); + + TRAPD(err,Create_Destroy_TestL()); + + test(err==KErrNone); + //This FinalClose() is purposely omitted for testing the PANIC + //REComSession::FinalClose(); + + delete threadcleanup; + __UHEAP_MARKEND; + return KErrNone; + } + +//The test code for creating and destroying an implementation +//To be used in the two test cases above +TInt RFinalCloseTest::Create_Destroy_TestL() + { + TUid dTorKey; + TUid implUid={0x101F8478}; + + // Set up some empty initialisation parameters + CExampleInterface::TExampleInterfaceInitParams initParams; + initParams.integer = 0; + initParams.descriptor = NULL; + + CExampleInterface* dllPtr = REINTERPRET_CAST(CExampleInterface*, + REComSession::CreateImplementationL(implUid,dTorKey,&initParams)); + + //Check the return implementation instantiation has the same implementation uid + test(dllPtr->ImplId()==implUid); + //The returned Uid to be used in Destruction should match the implementation uid as well + CInstanceInfoSimple* instanceInfo = reinterpret_cast (dTorKey.iUid); + test(instanceInfo->ImplementationUid()==implUid); + + REComSession::DestroyedImplementation(dTorKey); + + delete dllPtr; + dllPtr=0; + + return KErrNone; + } + +//The test code for listing implementation of an interface Uid. +//The test also verify all the implementations in the list by +//checking all the implementation Uid and their version. +void RFinalCloseTest::ListImplementation_TestL() + { + /** + Some Plugin in Z that can be used for testing purposes + Interface UID DLL UID Implementation UID Version DllFile + ------------------------------------------------------------------- + 0x10009DC0 0x10009DB1 0x10009DC3 1 Z:\\..\\EComExample.dll old_version + 0x10009DB1 0x10009DC4 1 Z:\\..\\EComExample.dll old_version + 0x10009DB3 0x10009DC3 2 Z:\\..\\EComExample2.dll = + 0x10009DB3 0x10009DC4 2 Z:\\..\\EComExample2.dll = + 0x101F8477 0x101F8478 1 Z:\\..\\EComExample3.dll = + 0x101F8479 0x101F847A 1 Z:\\..\\EComExample4.dll = + 0x10009DB2 0x10009DC5 1 Z:\\..\\Suidical.dll = + + */ + TUid interfaceUid={0x10009DC0}; + RImplInfoPtrArray implArray; + + //Array of all the expected implementation Uid; + RArray expectedUidArray; + expectedUidArray.Append(0x10009DC3); + expectedUidArray.Append(0x10009DC4); + expectedUidArray.Append(0x101F8478); + expectedUidArray.Append(0x101F847A); + expectedUidArray.Append(0x10009DC5); + + REComSession::ListImplementationsL(interfaceUid,implArray); + + //Expected number of implementations retured=5 + //This line has been removed as it is not safe to always assume there will be + //a fixed number of implementations based on an the interface 0x10009DC0. + //test(implArray.Count()==5); + + + //Check that the implementation uid returned matched the specs above + for (TInt i=0;iImplementationUid(); + if (expectedUidArray.Find(implUid.iUid)!=KErrNotFound) + { + //check for the latest version for 10009DC3 & 10009DC4 + if (implUid.iUid==0x10009DC3 || implUid.iUid==0x10009DC4) + test(implArray[i]->Version()==2); + //all the other implementations have version 1 + else + test(implArray[i]->Version()==1); + } + } + expectedUidArray.Reset(); + expectedUidArray.Close(); + implArray.ResetAndDestroy(); + } + +/** +The test code for testing the proper use of ListImplementationsL where +after calling that function we call REComSession::FinalClose() + +@SYMTestCaseID SYSLIB-ECOM-CT-0761 +@SYMTestCaseDesc Tests for proper listing of implementation of an interface UID +@SYMTestPriority High +@SYMTestActions Call up REComSession::FinalClose after ListImplementation_TestL +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +TInt RFinalCloseTest::ListImpl_With_FinalCloseL() + { + __UHEAP_MARK; + + ListImplementation_TestL(); + + REComSession::FinalClose(); + + __UHEAP_MARKEND; + + return KErrNone; + } + +/** +The test code for testing the improper use of ListImplementationsL where +after the call, we never invoke REComSession::FinalClose().This will +result in some memory leak panic. + +@SYMTestCaseID SYSLIB-ECOM-CT-0762 +@SYMTestCaseDesc Tests for proper listing of implementation of an interface UID +@SYMTestPriority High +@SYMTestActions Call to REComSession::FinalClose is omitted to show memory leak panic +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +TInt RFinalCloseTest::ListImpl_Without_FinalClose(TAny*) + { + + __UHEAP_MARK; + + CTrapCleanup* threadcleanup = CTrapCleanup::New(); + TRAPD(err,ListImplementation_TestL()); + test(err==KErrNone); + + //This FinalClose() is purposely omitted for testing the PANIC + //REComSession::FinalClose(); + + delete threadcleanup; + __UHEAP_MARKEND; + return KErrNone; + } +/** +The test code for testing the implementation creation and deletion +where we create two different implementation using two different plugins +destroy them and call FinalClose() to show there is no problem and memory leak + +@SYMTestCaseID SYSLIB-ECOM-CT-0763 +@SYMTestCaseDesc Tests for proper creation and deletion of implementation using two different plugins +@SYMTestPriority High +@SYMTestActions Create the implementation with a call to REComSession::CreateImplementationL twice with different UIDs + Signal the destruction of an interface implementation to ECOM with a call to REComSession::DestroyedImplementation + Call up REComSession::FinalClose +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +void RFinalCloseTest::Create_Destroy2_With_FinalCloseL() + { + __UHEAP_MARK; + + TUid implUid1={0x10009DC3}; + TUid implUid2={0x101F847A}; + TUid dTorKey1; + TUid dTorKey2; + // Set up some empty initialisation parameters + CExampleInterface::TExampleInterfaceInitParams initParams; + initParams.integer = 0; + initParams.descriptor = NULL; + + //Creating implementation 1 + CExampleInterface* impl1 = REINTERPRET_CAST(CExampleInterface*, + REComSession::CreateImplementationL(implUid1,dTorKey1,&initParams)); + test(impl1->ImplId()==implUid1); + + //Creating implementation 2 + CExampleInterface* impl2 = REINTERPRET_CAST(CExampleInterface*, + REComSession::CreateImplementationL(implUid2,dTorKey2,&initParams)); + test(impl2->ImplId()==implUid2); + + //Destroy implementation 2 + REComSession::DestroyedImplementation(dTorKey2); + + delete impl2; + impl2=0; + + //Now Destroy implementation 1 + REComSession::DestroyedImplementation(dTorKey1); + + delete impl1; + impl1=0; + + REComSession::FinalClose(); + + __UHEAP_MARKEND; + + } + +/** +The test code for testing that REComSession::FinalClose() can be called many times +without introducing any strange behaviour, memory leak and crash problem. + +@SYMTestCaseID SYSLIB-ECOM-CT-0764 +@SYMTestCaseDesc Tests to show that FinalClose() can be called many times with no unknown consequence. +@SYMTestPriority High +@SYMTestActions Create the implementation with some empty initialisation parameters + Call up REComSession::FinalClose twice before destroying the implementation and once after the deletion + Check for any strange behaviour, memory leak and crash problem. +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +void RFinalCloseTest::Create_Destroy3_With_FinalCloseL() + { + __UHEAP_MARK; + TUid implUid1={0x10009DC3}; + TUid dTorKey1; + // Set up some empty initialisation parameters + CExampleInterface::TExampleInterfaceInitParams initParams; + initParams.integer = 0; + initParams.descriptor = NULL; + + //Creating implementation 1 + CExampleInterface* impl1 = REINTERPRET_CAST(CExampleInterface*, + REComSession::CreateImplementationL(implUid1,dTorKey1,&initParams)); + test(impl1->ImplId()==implUid1); + + //Called FinalClose() twice + REComSession::FinalClose(); + REComSession::FinalClose(); + + REComSession::DestroyedImplementation(dTorKey1); + delete impl1; + + REComSession::FinalClose(); + + __UHEAP_MARKEND; + } + +/** +The test code for testing the functionality of REComSession::FinalClose() +without introducing any strange behaviour,memory leak and crash problem + +@SYMTestCaseID SYSLIB-ECOM-CT-0765 +@SYMTestCaseDesc Tests for the REComSession::FinalClose() function +@SYMTestPriority High +@SYMTestActions Open and close single connection to the the ECom server. + Call FinalClose, to check for any strange behaviour,memory leak and crash problem +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +void RFinalCloseTest::Create_Destroy4_With_FinalCloseL() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0765 ")); + __UHEAP_MARK; + + REComSession& ecomsession = ecomsession.OpenL(); + + ecomsession.Close(); + + REComSession::FinalClose(); + + __UHEAP_MARKEND; + } +/** +The test code for testing the functionality of REComSession::FinalClose() +without introducing any strange behaviour,memory leak and crash problem + +@SYMTestCaseID SYSLIB-ECOM-CT-0766 +@SYMTestCaseDesc Tests for the REComSession::FinalClose() function +@SYMTestPriority High +@SYMTestActions Call FinalClose() function,to check for any memory leak and crash problem +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +void RFinalCloseTest::FinalClose() + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0766 ")); + __UHEAP_MARK; + + REComSession::FinalClose(); + + __UHEAP_MARKEND; + } + +LOCAL_C void NonConstructL_Create_Destroy_helper() + { + REComSession session; + } + +/** +@SYMTestCaseID SYSLIB-ECOM-CT-0767 +@SYMTestCaseDesc Tests for the REComSession::FinalClose() function +@SYMTestPriority High +@SYMTestActions Open and close connection to ECOM server + Check for any memory leak and crash problem +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +void RFinalCloseTest::NonConstructL_Create_Destroy() + { + __UHEAP_MARK; + + // Test 1 + ::NonConstructL_Create_Destroy_helper(); + + // Test 2 + REComSession* ptr = new REComSession; + delete ptr; + + __UHEAP_MARKEND; + } + +/** +The test code is used for capturing the PANIC that occurs as a result of not +calling REComSession::FinalClose() when using ECOM plugins. + +@SYMTestCaseID SYSLIB-ECOM-CT-0768 +@SYMTestCaseDesc Tests for PANIC when REComSession::FinalClose() is called using ECOM plugins +@SYMTestPriority High +@SYMTestActions Check for memory leak panic +@SYMTestExpectedResults The test must not fail. +@SYMREQ REQ0000 +*/ +void RFinalCloseTest::ThreadPanicTest(const TDesC& aName,TThreadFunction aFunction) + { + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0768 ")); + test.Next(aName); + TRequestStatus threadStatus; + RThread thread; + TBool jit; + jit=User::JustInTime(); + User::SetJustInTime(EFalse); + + TInt err=thread.Create(aName,aFunction,KDefaultStackSize*8,KMinHeapSize,0x100000,0); + test(err==KErrNone); + thread.Logon(threadStatus) ; + thread.Resume(); + + User::WaitForRequest(threadStatus); + + //Now check why the thread Exit + + test(thread.ExitType()==EExitPanic); + test(thread.ExitReason()==0); + //A memory leak will have the exit category of form ALLOC:xxxxxx + //test.Printf(_L("Exit xcat: %S"), thread.ExitCategory().Left(6)); + test(thread.ExitCategory().Left(6).CompareF(_L("ALLOC:"))==0); + thread.Close(); + User::SetJustInTime(jit); + } + +/** +Copies the Plugins to specific folder for testing purpose +*/ +LOCAL_C void CopyPlugins() + { + // Copy the dlls and .rsc files on to RAM + TRAPD(err, EComTestUtils::FileManCopyFileL(KEComExDllOnZ, KEComExDllOnC)); + test(err==KErrNone); + + TRAP(err, EComTestUtils::FileManCopyFileL(KEComRscFileOnZ, KEComRscFileOnC)); + test(err==KErrNone); + + TRAP(err, EComTestUtils::FileManCopyFileL(KEComExampleDllOnZ, KEComExampleDllOnC)); + test(err==KErrNone); + TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample2DllOnZ, KEComExample2DllOnC)); + test(err==KErrNone); + TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample3DllOnZ, KEComExample3DllOnC)); + test(err==KErrNone); + + TRAP(err, EComTestUtils::FileManCopyFileL(KEComExampleRscOnZ, KEComExampleRscOnC)); + test(err==KErrNone); + TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample2RscOnZ, KEComExample2RscOnC)); + test(err==KErrNone); + TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample3RscOnZ, KEComExample3RscOnC)); + test(err==KErrNone); + } + +// Deleting plugin from the RAM for cleanup purpose +inline LOCAL_C void DeleteTestPlugin() + { + TRAPD(err, EComTestUtils::FileManDeleteFileL(KEComExDllOnC)); + TRAP(err, EComTestUtils::FileManDeleteFileL(KEComRscFileOnC)); + TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExampleDllOnC)); + TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample2DllOnC)); + TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample3DllOnC)); + TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExampleRscOnC)); + TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample2RscOnC)); + TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample3RscOnC)); + } + +LOCAL_C void RunTestL() + { + __UHEAP_MARK; + //Basic ECOM test + test.Next(_L("FinalClose")); + RFinalCloseTest::FinalClose(); + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0759 Create_Destroy_With_FinalCloseL ")); + RFinalCloseTest::Create_Destroy_With_FinalCloseL(); + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0761 ListImpl_With_FinalCloseL ")); + RFinalCloseTest::ListImpl_With_FinalCloseL(); + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0763 Create_Destroy2_With_FinalCloseL ")); + RFinalCloseTest::Create_Destroy2_With_FinalCloseL(); + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0764 Create_Destroy3_With_FinalCloseL ")); + RFinalCloseTest::Create_Destroy3_With_FinalCloseL(); + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0767 NonConstructL_Create_Destroy ")); + RFinalCloseTest::NonConstructL_Create_Destroy(); + + //ECOM FinalClose() Panic Test + #if defined(_DEBUG) + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0760 ")); + RFinalCloseTest::ThreadPanicTest(_L("Create Destroy Panic Testing"),RFinalCloseTest::Create_Destroy_Without_FinalClose); + test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0762 ")); + RFinalCloseTest::ThreadPanicTest(_L("List Implementation Panic Testing"),RFinalCloseTest::ListImpl_Without_FinalClose); + #endif + + __UHEAP_MARKEND; + } + +GLDEF_C TInt E32Main() + { + __UHEAP_MARK; + + test.Title(); + test.Start(_L("Final Close tests.")); + + CopyPlugins(); + + CTrapCleanup* cleanup = CTrapCleanup::New(); + CActiveScheduler* scheduler = new(ELeave)CActiveScheduler; + CActiveScheduler::Install(scheduler); + + TRAPD(err,RunTestL()); + test(err==KErrNone); + + // Cleanup files. If the cleanup fails that is no problem, + // as any subsequent tests will replace them. The only downside + // would be the disk not being tidied + DeleteTestPlugin(); + + delete scheduler; + delete cleanup; + + test.End(); + test.Close(); + + __UHEAP_MARKEND; + return(0); + }