lowlevellibsandfws/pluginfw/Framework/NotificationTest/t_ecomcancel.cpp
author hgs
Tue, 20 Jul 2010 16:35:53 +0530
changeset 44 97b0fb8a2cc2
parent 0 e4d67989cc36
child 57 2efc27d87e1c
permissions -rw-r--r--
201025

// Copyright (c) 2003-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 <e32test.h>
#include <ecom/ecom.h>
#include <f32file.h>
#include <e32base.h>
#include <bautils.h>
#include <e32ldr.h>

#include "../EcomTestUtils/EcomTestUtils.h"
#include "HeapTestInterface.h"

LOCAL_D RTest TheTest(_L("t_ecomcancel"));
LOCAL_D RFs TheFs;

const TInt KWaitDuration = 30000000; // retry delay in usecs

_LIT(KHTI_PluginAtRootOfZ,  "z:\\HeapTestImpl.dll");
_LIT(KHTI_PluginAtRootOfC,  "c:\\HeapTestImpl.dll");
_LIT(KHTIr_PluginAtRootOfZ, "z:\\HeapTestImpl.rsc");
_LIT(KHTIr_PluginAtRootOfC, "c:\\HeapTestImpl.rsc");
_LIT(KHTI_PluginInstalledOnC,  "c:\\sys\\bin\\HeapTestImpl.dll");
_LIT(KHTIr_PluginInstalledOnC, "c:\\resource\\plugins\\HeapTestImpl.rsc");

_LIT(KExample5DllOnC, "C:\\sys\\bin\\EComExample5.dll");
_LIT(KExample5DllOnZ, "z:\\RAMOnly\\EComExample5.dll");
_LIT(KExample5RscOnC, "C:\\resource\\plugins\\EComExample5.rsc");
_LIT(KExample5RscOnZ, "z:\\RAMOnly\\EComExample5.rsc");
_LIT(KExample5TmpRscOnC, "C:\\resource\\plugins\\EComExample5tmp.rsc");

void CleanupFiles()
	{
	TRAPD(ignoreErr, EComTestUtils::FileManDeleteFileL(KHTI_PluginInstalledOnC));
	TRAP(ignoreErr, EComTestUtils::FileManDeleteFileL(KHTIr_PluginInstalledOnC));

	TRAP(ignoreErr, EComTestUtils::FileManDeleteFileL(KExample5TmpRscOnC));
	TRAP(ignoreErr, EComTestUtils::FileManDeleteFileL(KExample5RscOnC));
	TRAP(ignoreErr, EComTestUtils::FileManDeleteFileL(KExample5DllOnC));

	WAIT_FOR3s;
	}

//
//
//Test macroses and functions
LOCAL_C void Check(TInt aValue, TInt aLine)
	{
	if(!aValue)
		{
		::CleanupFiles();
		TheTest(EFalse, aLine);
		}
	}
LOCAL_C void Check(TInt aValue, TInt aExpected, TInt aLine)
	{
	if(aValue != aExpected)
		{
		RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
		::CleanupFiles();
		TheTest(EFalse, aLine);
		}
	}
#define TEST(arg) ::Check((arg), __LINE__)
#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
//
//


// Setup files for test
void SetUpPlugins()
	{

	TInt err;
	TRAP(err, EComTestUtils::FileManCopyFileL(KHTI_PluginAtRootOfZ, KHTI_PluginAtRootOfC));
	TEST2(err, KErrNone);
	TRAP(err, EComTestUtils::FileManCopyFileL(KHTIr_PluginAtRootOfZ, KHTIr_PluginAtRootOfC));
	TEST2(err, KErrNone);
	TRAP(err, EComTestUtils::FileManCopyFileL(KHTI_PluginAtRootOfZ, KHTI_PluginInstalledOnC));
	TEST2(err, KErrNone);
	TRAP(err, EComTestUtils::FileManCopyFileL(KHTIr_PluginAtRootOfZ, KHTIr_PluginInstalledOnC));
	TEST2(err, KErrNone);
	WAIT_FOR3s;

	}

// Copying plugin to the RAM for test purposes
void CopyTestPlugin()
	{
	TRAPD(err, EComTestUtils::FileManCopyFileL(KExample5RscOnZ, KExample5RscOnC));
	TEST2(err, KErrNone);
	TRAP(err, EComTestUtils::FileManCopyFileL(KExample5DllOnZ, KExample5DllOnC));
	TEST2(err, KErrNone);
	WAIT_FOR3s;
	}

void ResetEComEnvironmentL()
	{
    ECOMTU_KILL_SERVER_L(TheTest);
	}


/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0657
@SYMTestCaseDesc	    De-Registering for notification of messages test
                        Test for REComSession class
@SYMTestPriority 	    High
@SYMTestActions  	    Test for no side effects on trying to cancel a request that has been already cancelled
						Test for updation of right status value after cancel request.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
void TestCancelL()
	{
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0657 TestCancelL "));

    // Test normal cancelling
    REComSession& session = REComSession::OpenL();
    TRequestStatus status;
    session.NotifyOnChange(status);
    session.CancelNotifyOnChange(status);
    User::WaitForRequest(status);
    TEST(status == KErrCancel);
    session.Close();

	// Test no side effects on trying to cancel a request
	//  that has already been cancelled
    session = REComSession::OpenL();
    session.NotifyOnChange(status);
    session.CancelNotifyOnChange(status);
    User::WaitForRequest(status);
    TEST(status == KErrCancel);
    session.CancelNotifyOnChange(status);
    session.CancelNotifyOnChange(status);
    TEST(status == KErrCancel);

	// Make sure the right status value is updated after a cancel request.
    TRequestStatus status1, status2, status3;
    session.NotifyOnChange(status);
    TEST(status==KRequestPending);
    session.NotifyOnChange(status1);
    TEST(status1==KRequestPending);
    session.NotifyOnChange(status2);
    TEST(status2==KRequestPending);
    session.NotifyOnChange(status3);
    TEST(status3==KRequestPending);
    session.CancelNotifyOnChange(status);
    User::WaitForRequest(status);
    TEST(status==KErrCancel);
    session.CancelNotifyOnChange(status3);
    session.CancelNotifyOnChange(status2);
    User::WaitForRequest(status3);
    TEST(status3==KErrCancel);
    User::WaitForRequest(status2);
    TEST(status2==KErrCancel);
    session.CancelNotifyOnChange(status1);
    User::WaitForRequest(status1);
    TEST(status1==KErrCancel);
   	session.Close();

	// Test Ends...
	REComSession::FinalClose();
	}


void SimulateDiskChangeL()
	{
	// Set up for heap leak checking
	__UHEAP_MARK;

	// Make sure the file is not read-only
	TRAPD(err, EComTestUtils::MakeFileWriteableL(KHTI_PluginAtRootOfC));
	TRAP(err, EComTestUtils::MakeFileWriteableL(KHTIr_PluginAtRootOfC));

	// Simulate that the implementation dll is changed - change resouce file timestamp
	RFile file;
	User::LeaveIfError(file.Open(TheFs, KHTIr_PluginAtRootOfC, EFileRead | EFileWrite));
	TTime time;
	User::LeaveIfError(file.Modified(time));
	TTimeIntervalSeconds interval = 100;
	time += interval;
	User::LeaveIfError(file.SetModified(time));
	file.Close();

	// Replace the resource file with the newer version (newer timestamp)
	// The ECOM server will run the discovery process and will unload the old dll
	// and replace it with the newer dll
	TRAP(err, EComTestUtils::FileManCopyFileL(KHTI_PluginAtRootOfC, KHTI_PluginInstalledOnC));
	TEST2(err, KErrNone);
	TRAP(err, EComTestUtils::FileManCopyFileL(KHTIr_PluginAtRootOfC, KHTIr_PluginInstalledOnC));
	TEST2(err, KErrNone);

	WAIT_FOR3s; // wait for copy to complete

	__UHEAP_MARKEND;
	}

// This test step no longer uses bafl to move files as it does not have high
// enough capability - uses CFileMan helper process instead.
void SimulatePluginDeleteBaflL()
	{
	// Set up for heap leak checking
	__UHEAP_MARK;

	// Make sure the file is not read-only
	TRAPD(err, EComTestUtils::MakeFileWriteableL(KExample5DllOnC));
	TRAP(err, EComTestUtils::MakeFileWriteableL(KExample5RscOnC));

	// Delete the plugins
	// The ECOM server will send the notification to its clients for change.
	TRAPD(ignoreErr, EComTestUtils::FileManDeleteFileL(KExample5RscOnC));
	TRAP(ignoreErr, EComTestUtils::FileManDeleteFileL(KExample5DllOnC));
	WAIT_FOR3s;

	__UHEAP_MARKEND;
	}

// This test step no longer uses bafl to move files as it does not have high
// enough capability - uses CFileMan helper process instead.
void SimulatePluginCopyBaflL()
	{
	// Set up for heap leak checking
	__UHEAP_MARK;


	// Make sure the file is not read-only
	TRAPD(err, EComTestUtils::MakeFileWriteableL(KExample5DllOnC));
	TRAP(err, EComTestUtils::MakeFileWriteableL(KExample5RscOnC));

	// Copy the plugins.
	// The ECOM server will send the notification to its clients for change.
	TRAP(err, EComTestUtils::FileManCopyFileL(KExample5RscOnZ, KExample5RscOnC));
	TEST2(err, KErrNone);
	TRAP(err, EComTestUtils::FileManCopyFileL(KExample5DllOnZ, KExample5DllOnC));
	TEST2(err, KErrNone);

	WAIT_FOR5s; // wait for copy to complete

	__UHEAP_MARKEND;
	}

void SimulatePluginDeleteFileManL()
	{
	// Set up for heap leak checking
	__UHEAP_MARK;

	// Make sure the file is read-only
	TRAPD(err, EComTestUtils::MakeFileWriteableL(KExample5DllOnC));
	TRAP(err, EComTestUtils::MakeFileWriteableL(KExample5RscOnC));


	// Delete the plugins.
	// The ECOM server will send the notification to its clients for change.
	TRAP(err, EComTestUtils::FileManDeleteFileL(KExample5RscOnC));
	TRAP(err, EComTestUtils::FileManDeleteFileL(KExample5DllOnC));

	WAIT_FOR5s; // wait for copy to complete

	__UHEAP_MARKEND;
	}

void SimulatePluginCopyFileManL()
	{
	// Set up for heap leak checking
	__UHEAP_MARK;

	// Make sure the file is not read-only
	TRAPD(err, EComTestUtils::MakeFileWriteableL(KExample5DllOnC));
	TRAP(err, EComTestUtils::MakeFileWriteableL(KExample5RscOnC));

	// Copy the plugins.
	// The ECOM server will send the notification to its clients for change.
	TRAP(err, EComTestUtils::FileManCopyFileL(KExample5RscOnZ, KExample5RscOnC));
	TEST2(err, KErrNone);
	TRAP(err, EComTestUtils::FileManCopyFileL(KExample5DllOnZ, KExample5DllOnC));
	TEST2(err, KErrNone);

	WAIT_FOR5s; // wait for copy to complete

	__UHEAP_MARKEND;
	}

void SimulatePluginDeleteRFsL()
	{
	// Set up for heap leak checking
	__UHEAP_MARK;

	// Make sure the file is read-only
	TRAPD(err, EComTestUtils::MakeFileWriteableL(KExample5DllOnC));
	TRAP(err, EComTestUtils::MakeFileWriteableL(KExample5RscOnC));

	// Delete the plugins using RFs.
	// The ECOM server will send the notification to its clients for change.
	TRAP(err, EComTestUtils::RfsDeleteFileL(KExample5RscOnC));
	TRAP(err, EComTestUtils::RfsDeleteFileL(KExample5DllOnC));

	WAIT_FOR5s; // wait for copy to complete

	__UHEAP_MARKEND;
	}

void SimulatePluginReplaceRFsL()
	{
	// Set up for heap leak checking
	__UHEAP_MARK;

	// Make sure the file is not read-only
	TRAPD(err, EComTestUtils::MakeFileWriteableL(KExample5DllOnC));

	// Replace the plugins using RFs.
	// The ECOM server will send the notification to its clients for change.
	TRAP(err, EComTestUtils::RfsReplaceFileL(KExample5RscOnC,KExample5TmpRscOnC));
	TEST2(err, KErrNone);

	WAIT_FOR5s; // wait for operation to complete

	__UHEAP_MARKEND;
	}


/**
@SYMTestCaseID          SYSLIB-ECOM-CT-0658
@SYMTestCaseDesc	    Tests for REComSession::NotifyOnChange() function
@SYMTestPriority 	    High
@SYMTestActions  	    Tests for changing the implementation dll(timestamp change) and checks for the notify status
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
void TestNotifyL()
	{
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-0658 TestNotifyL "));

	// Set up for heap leak checking
	__UHEAP_MARK;

	// and leaking thread handles
	TInt startProcessHandleCount;
	TInt startThreadHandleCount;
	TInt endProcessHandleCount;
	TInt endThreadHandleCount;

	// Test Starts...
	RThread thisThread;
	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);


	//-----
    REComSession& ecomSession = REComSession::OpenL();
	CleanupClosePushL(ecomSession);

	RTimer timer;
	CleanupClosePushL(timer);
	User::LeaveIfError(timer.CreateLocal());

	TRequestStatus timerStatus;
	TRequestStatus notifyStatus;

	// 1st disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 2nd disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 3rd disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 4th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 5th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 6th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 7th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 8th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 9th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 10th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulateDiskChangeL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	// 11th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginDeleteBaflL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Copy back the deleted plugin for the next test
	CopyTestPlugin();

	// 12th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change, but no regigstry data changed
	SimulatePluginCopyBaflL();

	User::WaitForAnyRequest();

	//since the file copied is same as before, no notify will be send
	TEST(notifyStatus==KRequestPending);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();


	// 13th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginDeleteFileManL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Copy back the deleted plugin for the next test
	CopyTestPlugin();

	// 14th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginCopyFileManL();

	User::WaitForAnyRequest();

	//since the file copied is same as before, no notify will be send
	TEST(notifyStatus==KRequestPending);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();


	// 15th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginDeleteRFsL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Copy back the deleted plugin for the next test
	CopyTestPlugin();

	// 16th disk change
	// Issue the requests
	timer.After(timerStatus, KWaitDuration);
	ecomSession.NotifyOnChange(notifyStatus);

	// simulate a disk change
	SimulatePluginReplaceRFsL();

	User::WaitForAnyRequest();

	TEST(notifyStatus==KErrNone);
	TEST(timerStatus==KRequestPending);

	timer.Cancel();

	//Replace back the deleted plugin.
	TRAPD(err, EComTestUtils::FileManCopyFileL(KExample5TmpRscOnC, KExample5RscOnC));
	TEST2(err, KErrNone);

	CleanupStack::PopAndDestroy(&timer);
	CleanupStack::PopAndDestroy(&ecomSession);
	//-----

	// Test Ends...
	REComSession::FinalClose();

	// Check for open handles
	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
	TEST(startThreadHandleCount == endThreadHandleCount);

	__UHEAP_MARKEND;

	}

/**
@SYMTestCaseID          SYSLIB-ECOM-CT-1808
@SYMTestCaseDesc	    Tests the uninstallation of an active plugin
@SYMTestPriority 	    High
@SYMTestActions  	    Creates a plugin implementation and then uninstalls the
                        plugin's files from the C: Drive and waits for an ECOM
                        notification completion, upon which it deletes the
                        plugin.
@SYMTestExpectedResults The test must not fail.
@SYMREQ                 REQ0000
*/
void TestUninstallL()
	{
	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-ECOM-CT-1808 TestUninstallL "));

	// Set up for heap leak checking and leaking thread handles
	__UHEAP_MARK;
	TInt startProcessHandleCount;
	TInt startThreadHandleCount;
	TInt endProcessHandleCount;
	TInt endThreadHandleCount;
	RThread thisThread;
	thisThread.HandleCount(startProcessHandleCount, startThreadHandleCount);

    // Step 1: Setup the session to ECOM
    TInt err = KErrNone;
    REComSession& ecomSession = REComSession::OpenL();
	CleanupClosePushL(ecomSession);

    // Step 2: Register for ECOM Server notification.
	TRequestStatus notifyStatus;
    ecomSession.NotifyOnChange(notifyStatus);
	TEST2(notifyStatus.Int(), KRequestPending);

    // Step 3. Create the plugin implementation we will uninstall
    TheTest.Printf(_L("CHeapTestInterface::NewL()\n"));
    CHeapTestInterface* implPtr = 0;
    TRAP(err, implPtr = CHeapTestInterface::NewL());
	TEST2(err, KErrNone);

    // Step 4. Simulate the uninstall of the plugin files
    TheTest.Printf(_L("Deleting HTI plugin - attempt 1, wait 5s...\n"));
  	//TRAP(err, EComTestUtils::FileManDeleteFileL(KHTI_PluginInstalledOnC));
  	TRAP(err, EComTestUtils::RLoaderDeleteFileL(KHTI_PluginInstalledOnC));
#if defined(__WINS__) || defined (__WINSCW__)
   	TEST2(err, KErrAccessDenied); // DLL File locked under Windows emulator due to it being demand paged
   	TheTest.Printf(_L("Error -21 (KErrAccessDenied) expected due to Windows keeping the DLL mapped in the emulator process adress space due to Windows demand paging/virtual memory system\n"));
#elif defined(__EPOC32__)
   	TEST2(err, KErrNone); // DLL File not locked on target hardware under SOS
//#else Do no test at all as its an unexpected platform.
#endif

 	TRAP(err, EComTestUtils::FileManDeleteFileL(KHTIr_PluginInstalledOnC));
   	TEST2(err, KErrNone);

    // Step 5. Wait for ECOM Server notification to arrive, with precautionary hang timer.
	RTimer timer;
	CleanupClosePushL(timer);
	User::LeaveIfError(timer.CreateLocal());
	TRequestStatus timerStatus;
	timer.After(timerStatus, KWaitDuration);
	TEST2(timerStatus.Int(), KRequestPending);

    TheTest.Printf(_L("Before calling WaitForAnyRequest(): Timer Status: %d; ECOM Notif Status: %d\n"), timerStatus.Int(), notifyStatus.Int());
    TheTest.Printf(_L("Checking notification recieved for ECOM Server...\n"));
    User::WaitForRequest(timerStatus, notifyStatus);

	TEST2(timerStatus.Int(), KRequestPending);
	TEST2(notifyStatus.Int(), KErrNone);
	timer.Cancel();

    // Step 6. Destroy the plugin
    TheTest.Printf(_L("DELETE implPtr\n"));
    delete implPtr;


	//CleanupStack::PopAndDestroy(&timer);
    TheTest.Printf(_L("Test over, cleanup...\n"));
   	CleanupStack::PopAndDestroy(&timer);
	CleanupStack::PopAndDestroy(&ecomSession);
	REComSession::FinalClose();

	// Check for open handles
	thisThread.HandleCount(endProcessHandleCount, endThreadHandleCount);
	TEST(startThreadHandleCount == endThreadHandleCount);

	// Test Ends...
	__UHEAP_MARKEND;

	}

void DoTestsL()
	{
	TestNotifyL();
	TestCancelL();
    TestUninstallL();
	}

GLDEF_C TInt E32Main()
	{
	__UHEAP_MARK;
	TheTest.Title();
	TheTest.Start(_L("Starting tests..."));
	TInt err = KErrNone;
	TInt r = KErrNone;

	CTrapCleanup* cleanup = CTrapCleanup::New();
	CActiveScheduler* scheduler = new(ELeave)CActiveScheduler;
	CActiveScheduler::Install(scheduler);
	r = TheFs.Connect();
	if (r != KErrNone)
		{
			return r;
		}

    // Reset the test environment under textshell in emulator/ROM
	TRAP(err, ResetEComEnvironmentL());
	TEST2(err, KErrNone);

	// Initial setup, runtests, cleanup
	SetUpPlugins();
	CopyTestPlugin();
	TRAP(err,DoTestsL());
	TEST2(err, KErrNone);
	CleanupFiles();

    // Reset the environment for next test executable
	TRAP(err, ResetEComEnvironmentL());
	TEST2(err, KErrNone);

	TheFs.Close();
	delete scheduler;
	delete cleanup;
	TheTest.End();
	TheTest.Close();

	__UHEAP_MARKEND;
	return(0);
	}