lowlevellibsandfws/pluginfw/Framework/SuicideTests/t_suicide.cpp
author Stefan Karlsson <stefan.karlsson@nokia.com>
Mon, 29 Mar 2010 12:27:51 +0100
branchCompilerCompatibility
changeset 14 69a2780c0013
parent 0 e4d67989cc36
permissions -rw-r--r--
Merge.

// Copyright (c) 2005-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:
// This file contains tests for testing resolver related
// functionality linking against ecom.lib, i.e. using public API
// Where necessary stubs are implemented to help in writing test
// harness using RTest.
// This test assumes the following setup:
// DLL			/Dll UID
// EComExample /10009DB1 on Z:
// EComExample2/10009DB3 on Z:
// EComExample3/101F8477 on Z:
// EComExample4/101F8479 on Z:
// EComExample5/101F847B on C:
// Suicidal    /10009DB2 on Z:
// EComExample6/0x101F847D on Z:
// The tests work by checking that the correct implementations are chosen
// for interface 0x10009DC0 depending on parameters passed
// Implementations:
// Impl ID		On C:		On Z: e.g:Version/Default_data/dll_uid
// 10009DC3	-			Ver 1/"text/ wml"/10009DB1, Ver 2/"text/ wml"/10009DB3
// 10009DC4	-			Ver 1/"text/ *"/10009DB1,   Ver 2/"text/ *"/10009DB3
// 101F8478	-			Ver 1/""/101F8477
// 101F847A	-			Ver 1/""/101F8479
// 101F847C	Ver 1/""/101F847B	-
// 10009DC5	-			Ver 1/"Suicide"/10009DB2
// 101F847E	on Z		Ver 1/""/101F847D
// 
//

#include <ecom/ecom.h>
#include "EComUidCodes.h"
#include "Interface.h" // interface to Plugins
#include "../EcomTestUtils/EcomTestUtils.h"

#include <e32test.h>
#include <f32file.h>
#include <bautils.h>

LOCAL_D RTest test(_L("t_suicide.exe"));

LOCAL_D CTrapCleanup* 	  TheTrapCleanup 	 = NULL;

LOCAL_D CActiveScheduler* TheActiveScheduler = NULL;

// Used for supressing warning in OOM tests
#define __UNUSED_VAR(var) var = var

const TInt KOneSecond		= 1000000;

// Interface ID used for testing
const TUid KUidInterface	= {0x10009DC0};

// Resolver ID used for testing
const TUid KUidResolver		= {0x10009DD0};

// Implementaion ID used for testing
const TUid KUidTestImplementation = {0x10009DC5};

// Interface Implementation Uids used for testing
const TInt KUidImplementation1 = 0x10009DC3;
const TInt KUidImplementation2 = 0x10009DC4;
const TInt KUidImplementation3 = 0x10009DC5;
const TInt KUidImplementation4 = 0x101F8478;
const TInt KUidImplementation5 = 0x101F847A;
const TInt KUidImplementation6 = 0x101F847C;
const TInt KUidImplementation7 = 0x101F847E;

// Match string used for testing
_LIT8(KInterfaceResolveMatchStr,"suicidal");

_LIT(KSysBinDirectoryWildcard, "c:\\sys\\bin\\*.dll");
_LIT(KResourceDirectoryWildcard, "c:\\resource\\plugins\\*.rsc");

// Plugins used for this test program
_LIT(KEComExample5OnZ,		"z:\\RAMOnly\\EComExample5.dll");

_LIT(KEComExample5OnC,		"c:\\sys\\bin\\EComExample5.dll");
_LIT(KEComExample5RscOnC,	"c:\\resource\\plugins\\EComExample5.rsc");
_LIT(KEComExample4OnC,		"c:\\sys\\bin\\EComExample4.dll");
_LIT(KEComExample4RscOnC,	"c:\\resource\\plugins\\EComExample4.rsc");
// ROM file copied to the RAM for test purposes
_LIT(KEComExample5RscOnZ,	"z:\\RAMOnly\\EComExample5.rsc");


// Utility clean up function
LOCAL_C void CleanupEComArray(TAny* aArray);

//It is used by some test methods which are called two times:
//from normal test and from OOM test.
static void LeaveIfErrNoMemory(TInt aError)
	{
	if(aError == KErrNoMemory)
		{
		REComSession::FinalClose();
		User::Leave(aError);
		}
	}

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0709
@SYMTestCaseDesc	    Tests for creation of plugin with resolver match string
@SYMTestPriority 	    High
@SYMTestActions  	    Checks for no error condition
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
LOCAL_C void TestCreateImplSuicideL()
	{
	// Tests creation of plugin with resolver match string
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0709 "));

	/* This should pick
	10009DC5	Ver 1/"Suicide"/10009DB2
	*/
	CExampleInterface* interfaceimpl = NULL;
	TRAPD(err, interfaceimpl = CExampleInterface::NewL(KInterfaceResolveMatchStr()));
	::LeaveIfErrNoMemory(err);
	test(err == KErrNone);
	CleanupStack::PushL(interfaceimpl);

	test(KUidTestImplementation == interfaceimpl->ImplId());

	TRAP(err, interfaceimpl->DoMethodL());
	::LeaveIfErrNoMemory(err);
	test(err == KErrNone);

	CleanupStack::PopAndDestroy(interfaceimpl);
	}

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0710
@SYMTestCaseDesc	    Tests for Listing all Implementations for the Interface KUidInterface
@SYMTestPriority 	    High
@SYMTestActions  	    Calls up REComSession::ListImplementationsL with interface UID.Picks up 6 implementations.
                        Checks for no memory exceptions.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
LOCAL_C void TestListAllImplL()
	{
	// Test for Listing all Implementations for the Interface KUidInterface
	//
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0710 "));

	RImplInfoPtrArray ifArray;
	CleanupStack::PushL(TCleanupItem(CleanupEComArray, &ifArray));

	TRAPD(err, REComSession::ListImplementationsL(KUidInterface, ifArray));
	::LeaveIfErrNoMemory(err);
	test(err == KErrNone);

	/* This should pick 6 implementations given below
	10009DC3	Ver 2/"text/ wml"/10009DB3
	10009DC4	Ver 2/"text/ *"/10009DB3
	101F8478	Ver 1/""/101F8477
	101F847A	Ver 1/""/101F8479
	101F847C	Ver 1/""/101F847B
	10009DC5	Ver 1/"Suicide"/10009DB2
	101F847E	Ver 1/""/101F847D
	*/

	const TInt availCount = ifArray.Count();
	test.Printf(_L("Found %d implementations.\n"),availCount);
	test(availCount == 7);

	for (TInt count=0;count<availCount;++count)
		{
		const CImplementationInformation* info = ifArray[count];

		TDriveName driveName = info->Drive().Name();
		test.Printf(_L("%d. uid={%x} version=%d on drive %S\n"), count+1, info->ImplementationUid(), info->Version(), &driveName);

		switch(info->ImplementationUid().iUid)
			{
			case KUidImplementation1:
				test(info->Version()==2);
				test(info->Drive()==EDriveZ);
				break;

			case KUidImplementation2:
				test(info->Version()==2);
				test(info->Drive()==EDriveZ);
				break;

			case KUidImplementation3:
				test(info->Version()==1);
				test(info->Drive()==EDriveZ);
				break;

			case KUidImplementation4:
				test(info->Version()==1);
				test(info->Drive()==EDriveZ);
				break;

			case KUidImplementation5:
				test(info->Version()==1);
				test(info->Drive()==EDriveZ);
				break;

			case KUidImplementation6:
				test(info->Version()==1);
				test(info->Drive()==EDriveC);
				break;

			case KUidImplementation7:
				test(info->Version()==1);
				test(info->Drive()==EDriveZ);
				break;

			default:
				test.Printf(_L("Unknown implementation Uid\n"));
				test(EFalse);
			}
		}
	// Empty the array of implementations
	CleanupStack::PopAndDestroy();//ifArray, results in a call to CleanupEComArray
	}

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0711
@SYMTestCaseDesc	    Tests to list all implementations for an interface with specified
						match string and wildcard match
@SYMTestPriority 	    High
@SYMTestActions  	    Calls up REComSession::ListImplementationsL with interface UID and resolver matching characteristics
                        Checks for no memory exceptions.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
LOCAL_C void TestListImplMatchStrWildcardL()
	{
	// Test to list all implementations for an interface with match string
	// and wildcard match
	//
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0711 "));

	TEComResolverParams resolverParams;
	_LIT8(KImplementationTest,"text/wml");
	resolverParams.SetDataType(KImplementationTest());//Match string
	resolverParams.SetGenericMatch(ETrue);	// Allow wildcard matching

	RImplInfoPtrArray ifArray;
	CleanupStack::PushL(TCleanupItem(CleanupEComArray, &ifArray));

	TRAPD(err, REComSession::ListImplementationsL(KUidInterface, resolverParams, ifArray));
	::LeaveIfErrNoMemory(err);
	test(err == KErrNone);

	/* This should pick 2 implementations given below
	10009DC3	Ver 2/"text/ wml"/10009DB3
	10009DC4	Ver 2/"text/ *"/10009DB3
	*/

	const TInt availCount = ifArray.Count();
	test.Printf(_L("Found %d implementations.\n"),availCount);
	test(availCount == 2);

	for (TInt count=0;count<availCount;++count)
		{
		const CImplementationInformation* info = ifArray[count];

		TDriveName driveName = info->Drive().Name();
		test.Printf(_L("%d. uid={%x} version=%d on drive %S\n"), count+1, info->ImplementationUid(), info->Version(), &driveName);

		switch(info->ImplementationUid().iUid)
			{
			case KUidImplementation1:
				test(info->Version()==2);
				test(info->Drive()==EDriveZ);
				break;

			case KUidImplementation2:
				test(info->Version()==2);
				test(info->Drive()==EDriveZ);
				break;

			default:
				test.Printf(_L("Unknown implementation UID\n"));
				test(EFalse);
			}
		}

	// Empty the array of implementations
	CleanupStack::PopAndDestroy();//ifArray, results in a call to CleanupEComArray
	}

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0712
@SYMTestCaseDesc	    Tests to list all implementations for an interface with specified
						match string and no wildcard match
@SYMTestPriority 	    High
@SYMTestActions  	    Calls up REComSession::ListImplementationsL with interface UID and resolver matching characteristics
                        Checks for no memory exceptions.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
LOCAL_C void TestListImplMatchStrL()
	{
	// Test to list all implementations for an interface with specified
	// match string and no wildcard match
	//
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0712 "));

	TEComResolverParams resolverParams;
	_LIT8(KImplementationTest,"text/wml");
	resolverParams.SetDataType(KImplementationTest());//Match string
	resolverParams.SetGenericMatch(EFalse);	// Don't allow wildcard matching

	RImplInfoPtrArray ifArray;
	CleanupStack::PushL(TCleanupItem(CleanupEComArray, &ifArray));

	TRAPD(err, REComSession::ListImplementationsL(KUidInterface, resolverParams, ifArray));
	::LeaveIfErrNoMemory(err);
	test(err == KErrNone);

	const TInt availCount = ifArray.Count();
	test.Printf(_L("Found %d implementations.\n"),availCount);
	test(availCount == 1);

	/* This should pick
	10009DC3	Ver 2/"text/wml"/10009DB3
	*/

	for (TInt count=0;count<availCount;++count)
		{
		const CImplementationInformation* info = ifArray[count];

		TDriveName driveName = info->Drive().Name();
		test.Printf(_L("%d. uid={%x} version=%d on drive %S\n"),
					count+1, info->ImplementationUid(), info->Version(), &driveName);

		switch(info->ImplementationUid().iUid)
			{
			case KUidImplementation1:
				test(info->Version()==2);
				test(info->Drive()==EDriveZ);
				break;

			default:
				test.Printf(_L("Unknown implementation Uid\n"));
				test(EFalse);
			}
		}
	// Empty the array of implementations
	CleanupStack::PopAndDestroy();//ifArray, results in a call to CleanupEComArray
	}

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0713
@SYMTestCaseDesc	    Tests to list all Implementations for an Interface with specified
						Resolver ID, Match String and Wildcard match
@SYMTestPriority 	    High
@SYMTestActions  	    Calls up REComSession::ListImplementationsL with interface UID Resolver ID, matching characteristics
                        Checks for no memory exceptions.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
LOCAL_C void TestListAllImplResolverIDL()
	{
	// Test to list all Implementations for an Interface with specified
	// Resolver ID, Match String and Wildcard match
	//
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0713 "));

	TEComResolverParams resolverParams;
	resolverParams.SetDataType(KInterfaceResolveMatchStr());
	resolverParams.SetGenericMatch(ETrue);	// Allow wildcard matching

	RImplInfoPtrArray ifArray;
	CleanupStack::PushL(TCleanupItem(CleanupEComArray, &ifArray));

	TRAPD(err, REComSession::ListImplementationsL(KUidInterface,
												  resolverParams,
												  KUidResolver,
												  ifArray));
	::LeaveIfErrNoMemory(err);
	test(err == KErrNone);

	const TInt availCount = ifArray.Count();
	test.Printf(_L("Found %d implementations.\n"), availCount);
	test(availCount == 1);

	/* This should pick
	10009DC5	Ver 1/"Suicide"/10009DB2
	*/

	for (TInt count=0;count<availCount;++count)
		{
		const CImplementationInformation* info = ifArray[count];

		TDriveName driveName = info->Drive().Name();
		test.Printf(_L("%d. uid={%x} version=%d on drive %S\n"), count+1, info->ImplementationUid(), info->Version(), &driveName);

		switch(info->ImplementationUid().iUid)
			{
			case KUidImplementation3:
				test(info->Version()==1);
				test(info->Drive()==EDriveZ);
				break;

			default:
				test.Printf(_L("Unknown implementation UID\n"));
				test(EFalse);
			}
		}

	// Empty the array of implementations
	CleanupStack::PopAndDestroy();//ifArray, results in a call to CleanupEComArray
	}

typedef void (*ClassFuncPtrL) (void);

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0714
@SYMTestCaseDesc	    Function to call all test functions
@SYMTestPriority 	    High
@SYMTestActions  	    Calls up test function and checks for handle counts.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
/**
Wrapper function to call all test functions

@param		testFuncL pointer to test function
@param		aTestDesc test function name
*/
LOCAL_C void DoBasicTestL(ClassFuncPtrL testFuncL, const TDesC& aTestDesc)
	{
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0714 "));
	test.Next(aTestDesc);

	__UHEAP_MARK;
  	// find out the number of open handles
	TInt startProcessHandleCount;
	TInt startThreadHandleCount;
	RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);

	//Call the test function
	(*testFuncL)();

	REComSession::FinalClose();

	// check that no handles have leaked
	TInt endProcessHandleCount;
	TInt endThreadHandleCount;
	RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);

	test(startThreadHandleCount  == endThreadHandleCount);

	__UHEAP_MARKEND;
	}

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0715
@SYMTestCaseDesc	    Wrapper function to call all OOM test functions
@SYMTestPriority 	    High
@SYMTestActions  	    Calls up test function and checks for handle counts.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
/**
Wrapper function to call all OOM test functions

@param		testFuncL pointer to OOM test function
@param		aTestDesc test function name
*/
LOCAL_C void DoOOMTest(ClassFuncPtrL testFuncL, const TDesC& aTestDesc)
	{
	test.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0715 "));
	test.Next(aTestDesc);

	TInt err, tryCount = 0;
	do
		{
		__UHEAP_MARK;
  		// find out the number of open handles
		TInt startProcessHandleCount;
		TInt startThreadHandleCount;
		RThread().HandleCount(startProcessHandleCount, startThreadHandleCount);

		// Setting Heap failure for OOM test
		__UHEAP_SETFAIL(RHeap::EDeterministic, ++tryCount);

		TRAP(err, (*testFuncL)());

		__UHEAP_SETFAIL(RHeap::ENone, 0);

		// release handles
		if(err == KErrNone)
			{
			REComSession::FinalClose();
			}

		// check that no handles have leaked
		TInt endProcessHandleCount;
		TInt endThreadHandleCount;
		RThread().HandleCount(endProcessHandleCount, endThreadHandleCount);

		test(startProcessHandleCount == endProcessHandleCount);
		test(startThreadHandleCount  == endThreadHandleCount);

		__UHEAP_MARKEND;
		} while(err == KErrNoMemory);

	test(err == KErrNone);
	test.Printf(_L("- server succeeded at heap failure rate of %i\n"), tryCount);
	}

LOCAL_C void DoTestsL()
	{
	__UHEAP_MARK;

	// Basic tests
	DoBasicTestL(TestCreateImplSuicideL, _L("TestCreateImplSuicideL"));
	DoBasicTestL(TestListImplMatchStrL, _L("TestListImplMatchStrL"));
	DoBasicTestL(TestListImplMatchStrWildcardL, _L("TestListImplMatchStrWildcardL"));
	DoBasicTestL(TestListAllImplL, _L("TestListAllImplL"));
	DoBasicTestL(TestListAllImplResolverIDL, _L("TestListAllImplResolverIDL"));

	// OOM tests
	DoOOMTest(TestCreateImplSuicideL, _L("OOM TestCreateImplSuicide"));
	DoOOMTest(TestListImplMatchStrL, _L("OOM TestListImplMatchStr"));
	DoOOMTest(TestListImplMatchStrWildcardL, _L("OOM TestListImplMatchStrWildcard"));
	DoOOMTest(TestListAllImplL, _L("OOM TestListAllImpl"));
	DoOOMTest(TestListAllImplResolverIDL, _L("OOM TestListAllImplResolverID"));

	__UHEAP_MARKEND;
	}

// This function is used for cleanup support of locally declared arrays
LOCAL_C void CleanupEComArray(TAny* aArray)
	{
	(static_cast<RImplInfoPtrArray*>(aArray))->ResetAndDestroy();
	}

// Deleting plugin from the RAM for cleanup purpose
inline LOCAL_C void DeleteTestPlugins()
	{
	TRAPD(err, EComTestUtils::FileManDeleteFileL(KSysBinDirectoryWildcard));
	TRAP(err, EComTestUtils::FileManDeleteFileL(KResourceDirectoryWildcard));
	}

// Copies the Plugins to specific folder for testing purpose
LOCAL_C void CopyPlugins()
	{
	DeleteTestPlugins();

	TRAPD(err, EComTestUtils::FileManCopyFileL(KEComExample5OnZ, KEComExample5OnC));
	test(err==KErrNone);

	TRAP(err, EComTestUtils::FileManCopyFileL(KEComExample5RscOnZ, KEComExample5RscOnC));
	test(err==KErrNone);

	// KEComExample4OnC & KEComExample4RscOnC are copied to C: Drive for
	// testing in t_listimplementation test program. These files should
	// be present in Z:. Please make sure these are present in Z only.
	TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample4OnC));
	TRAP(err, EComTestUtils::FileManDeleteFileL(KEComExample4RscOnC));
	}


//Initialise the Active Scheduler
//
LOCAL_C void SetupL()
	{
	// Construct and install the Active Scheduler. The Active Schedular is needed
	// by components used by this test as they are ActiveObjects.
	TheActiveScheduler = new(ELeave)CActiveScheduler;
	CActiveScheduler::Install(TheActiveScheduler);
	}

GLDEF_C TInt E32Main()
	{
	__UHEAP_MARK;

	test.Printf(_L("\n"));
	test.Title();
	test.Start(_L("Suicide Tests"));

	TheTrapCleanup = CTrapCleanup::New();
	TRAPD(err, SetupL());
	test(err == KErrNone);

	CopyPlugins();
	// The reason for the folowing delay is:
	// ECOM server could be already started. It means that when we copy some
	// ECOM plugins from Z: to C: drive - ECOM server should look for and
	// find the new ECOM plugins. The ECOM server uses for that an active object,
	// which scans plugin directories. So the discovering service is asynchronous.
	// We have to wait some time until it finishes.
	// Otherwise ListImplementationsL could fail to find requested implementations.
	User::After(KOneSecond * 3);

	TRAP(err,DoTestsL());
	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
	DeleteTestPlugins();

	delete TheActiveScheduler;
	delete TheTrapCleanup;

	test.End();
	test.Close();

	__UHEAP_MARKEND;
	return (KErrNone);
	}