appfw/apparchitecture/tef/T_OOMStep.cpp
author William Roberts <williamr@symbian.org>
Fri, 23 Apr 2010 14:37:17 +0100
branchRCL_3
changeset 22 c82a39b81a38
parent 0 2e3d3ce01487
permissions -rw-r--r--
Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414) Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can arrange to use the same source file name in sfimage, without having to export over the original Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.

// 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:
// Performs the Out of Memory Tests.\n
// 
// t_oomstep.cpp
//

/**
 @file t_oomstep.cpp
 @internalComponent - Internal Symbian test code  
*/

#include <f32file.h>
#include <apaid.h>
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <apaidpartner.h>
#include <apgicnflpartner.h>
#endif //SYMBIAN_ENABLE_SPLIT_HEADERS
#include <apgaplst.h>
#include <apgicnfl.h>
#include <apgdoor.h>
#include "tstapp.h"
#include <fbs.h>
#include <s32std.h> 
#include <s32stor.h> 
#include <s32file.h> 
#include <s32mem.h>
#include "T_OOMStep.h"
//
#if !defined(__E32TEST_H__)
#include <e32test.h>
#endif


void CT_OOMStep::setup()
	{
#if defined(__EPOC32__)
	TFullName filePath=_L("c:\\docs\\tstapp.doc");
	TFullName tempPath=_L("c:\\system\\temp\\");
	// if we're on the rack create the directories we need
	TParse parser;
	parser.Set(filePath,NULL,NULL);
	iFs.MkDirAll(parser.DriveAndPath());
	parser.Set(tempPath,NULL,NULL);
	iFs.MkDirAll(parser.DriveAndPath());
#endif
	}



/**
  Auxiliary Fn for Test Case ID T-OOMStep-TestOOMConstructionL 
 
  This function adds a new document to the app DLL and associates a 
  temporary store. The document is then initialized with the default settings.
*/
CApaDocument* CT_OOMStep::CreateTestDocL(CApaProcess* aProcess)
	{

	TFileName dllname=_L("tstapp.app");
	TFullName filePath=_L("c:\\docs\\tstapp.doc");
	// create a new main doc of type tstapp
	CApaDocument* doc=NULL;
	
	TApaApplicationFactory appFact(KUidTestApp);
	doc=aProcess->AddNewDocumentL(appFact);

	aProcess->SetMainDocument(doc);
	//
	// create the store and initialise it
	CFileStore* store = doc->CreateFileStoreLC(aProcess->FsSession(),filePath);
	CleanupStack::Pop(); // store
	((CTestAppDoc*)aProcess->MainDocument())->iStore = store;
	aProcess->SetMainDocFileName(filePath);
	//
	// initialise the document with factory settings
	doc->NewDocumentL();
	//
	return doc;
	}


/**
  Auxiliary Fn for Test Case ID T-OOMStep-TestOOMConstructionL 
 
  This function creates a test document for app DLL and saves
  the document.
  
*/
void CT_OOMStep::CreateTestDocFileL()
	{

	TFullName filePath=_L("c:\\docs\\tstapp.doc");
	// delete the file to be created by the testcode
	iFs.Delete(filePath);
	iFs.MkDir(_L("c:\\docs\\"));

	// create an appfinder and process
	CApaProcess* process = CApaProcess::NewL(iFs);
	CApaDocument* doc = CreateTestDocL(process);

	// save it 
	doc->SaveL();

	// tidy up
	process->DestroyDocument(doc);
	delete process;
	}

/**
   @SYMTestCaseID T-OOMStep-TestOOMConstructionL
  
   @SYMPREQ
  
   @SYMTestCaseDesc Test methods CApaScanningAppFinder::NewL, CApaProcess::NewL,
   CApaProcess::AddNewDocumentL, CApaProcess::OpenNewDocumentL and CApaDocument::SaveL
   when device goes Out of Memory.
   
   @SYMTestPriority High 
 
   @SYMTestStatus Implemented
   
   @SYMTestActions \n OOM Test for CApaScanningAppFinder::NewL:\n
   Use macro __UHEAP_SETFAIL() to simulate the out of memory
   situation. Call CApaScanningAppFinder::NewL() to allocate memory. Observe
   the leave that occurs. Observe after how many allocations the leave occurs.\n\n
   OOM Test for CApaProcess::NewL:\n
   Use macro __UHEAP_SETFAIL() to simulate the out of memory situation. Call
   CApaProcess::NewL() to allocate memory. Observe the leave that occurs.
   Observe after how many allocations the leave occurs.\n\n
   OOM Test for CApaProcess::AddNewDocumentL:\n
   Use macro __UHEAP_SETFAIL() to simulate the out of memory situation. Call
   CApaProcess::AddNewDocumentL() to allocate memory. Observe the leave that
   occurs. Observe after how many allocations the leave occurs.\n\n
   OOM Test for CApaProcess::OpenNewDocumentL:\n
   Use macro __UHEAP_SETFAIL() to simulate the out of memory situation. Call
   CApaProcess::OpenNewDocumentL() to allocate memory. Observe the leave that
   occurs. Observe after how many allocations the leave occurs.\n\n
   OOM Test for CApaDocument::SaveL:\n
   Create and initialize a document for tstapp. Use macro __UHEAP_SETFAIL()
   to simulate the out of memory situation. Call CApaDocument::SaveL() to
   allocate memory for the document to be saved. Observe the leave that occurs.
   Observe after how many allocations the leave occurs.\n\n
   API Calls:\n	
   CApaScanningAppFinder::NewL(const RFs& aFs)\n
   CApaProcess::NewL(const RFs& aFs,CApaAppFinder& aAppFinder)\n
   CApaProcess::AddNewDocumentL(const TDesC& aDllFileName,TUid aDllUid=KNullUid)\n
   CApaProcess::OpenNewDocumentL(CFileStore*& aStore,CStreamDictionary*& aStreamDic,const TDesC& aDocFullFileName,TUint aFileMode)\n
   CApaDocument::SaveL()\n
   
   @SYMTestExpectedResults Tests should complete without any memory leaks. It should
   also observe the no of allocations which occur before OOM situation.
    
 */
void CT_OOMStep::TestOOMConstructionL()
	{
	TInt failRate=0;
	TFullName filePath=_L("c:\\docs\\tstapp.doc");

	__UHEAP_RESET;

	// CApaProcess
	INFO_PRINTF1(_L("CApaProcess construction under OOM"));
	CApaProcess* process=NULL;
	for (failRate=1;;failRate++)
		{
		__UHEAP_RESET;
		__UHEAP_SETFAIL(RHeap::EDeterministic,failRate);
		__UHEAP_MARK;

		TRAPD(ret, process = CApaProcess::NewL(iFs));
		
			TEST((ret==KErrNone || ret==KErrNoMemory));
		if (ret!=KErrNone)
			{
			__UHEAP_MARKEND;
			TEST(process==NULL);
			}
		else
			{
			TEST(process!=NULL);
			delete process;
			process = NULL;
			REComSession::FinalClose();
			__UHEAP_MARKEND;
			break;
			}
		}
	__UHEAP_RESET;
	INFO_PRINTF2(_L("  #allocs for c'tion: %d\n"),failRate-1);
	//
	// creating CApaDocument
	INFO_PRINTF1(_L("CApaDocument construction under OOM"));
	CApaDocument* doc=NULL;
	//
	for (failRate=1;;failRate++)
		{
		__UHEAP_RESET;
		process = CApaProcess::NewL(iFs);		
			TEST(process!=NULL);
		__UHEAP_SETFAIL(RHeap::EDeterministic,failRate);
		__UHEAP_MARK;
		
		TApaApplicationFactory appFact(KUidTestApp);
		TRAPD(ret,doc=process->AddNewDocumentL(appFact));

		TEST((ret==KErrNone || ret==KErrNoMemory));
		if (ret!=KErrNone)
			{
			delete process;
			REComSession::FinalClose();
			__UHEAP_MARKEND;
			TEST(doc==NULL);
			}
		else
			{
			TEST(doc!=NULL);
			process->DestroyDocument(doc);
			delete process;
			REComSession::FinalClose();
			__UHEAP_MARKEND;
			break;
			}
		}
	__UHEAP_RESET;
	INFO_PRINTF2(_L("  #allocs for c'tion: %d\n"),failRate-1);
	//
	// opening a CApaDocument
	INFO_PRINTF1(_L("CApaDocument Restoration under OOM"));
	TRAPD(err,CreateTestDocFileL());
		TEST(err==KErrNone);
	//
	for (failRate=1;;failRate++)
		{
		__UHEAP_RESET;
		doc = NULL;
		process = CApaProcess::NewL(iFs);		

		__UHEAP_SETFAIL(RHeap::EDeterministic,failRate);
		__UHEAP_MARK;
		CFileStore* store=NULL;
		CStreamDictionary* streamDic=NULL;
		TRAPD(ret, doc=process->OpenNewDocumentL(store,streamDic,filePath,EFileShareExclusive|EFileWrite));
			TEST((ret==KErrNone || ret==KErrNoMemory));
		if (ret!=KErrNone)
			{
			delete streamDic;
			delete store;
			delete process;
			REComSession::FinalClose();
			__UHEAP_MARKEND;
			TEST(doc==NULL);
			}
		else
			{
			TEST(doc!=NULL);
			TEST(streamDic!=NULL);
			TEST(store!=NULL);
			delete streamDic;
			delete store;
			process->DestroyDocument(doc);
			delete process;
			REComSession::FinalClose();
			__UHEAP_MARKEND;
			break;
			}
		}
	__UHEAP_RESET;
	INFO_PRINTF2(_L("  #allocs for c'tion: %d\n"),failRate-1);
	//
	// saving a CApaDocument
	INFO_PRINTF1(_L("CApaDocument Storing under OOM"));
	//
	for (failRate=1;;failRate++)
		{
		__UHEAP_RESET;
		// delete the file to be created by the testcode
		iFs.Delete(filePath);
		process = CApaProcess::NewL(iFs);		
		doc = CreateTestDocL(process);
		// attempt to save
		__UHEAP_SETFAIL(RHeap::EDeterministic,failRate);
		__UHEAP_MARK;
		TRAPD(ret, doc->SaveL());
			TEST((ret==KErrNone || ret==KErrNoMemory));
		if (ret!=KErrNone)
			{
			process->DestroyDocument(doc);
			delete process;
			REComSession::FinalClose();
			__UHEAP_MARKEND;
			}
		else
			{
			process->DestroyDocument(doc);
			delete process;
			REComSession::FinalClose();
			__UHEAP_MARKEND;
			break;
			}
		}
	__UHEAP_RESET;
	INFO_PRINTF2(_L("  #allocs for c'tion: %d\n"),failRate-1);
	//
	}

/**
   @SYMTestCaseID T-OOMStep-TestDoorOOML
  
   @SYMPREQ
  
   @SYMTestCaseDesc Test CApaDoor APIs NewL(), StoreL(), Restore() when device
   goes Out of Memory.
   
   @SYMTestPriority High 
  
   @SYMTestStatus Implemented
   
   @SYMTestActions The method simulates an OOM scenario to test CApaDoor APIs NewL(),
   StoreL() and Restore().\n\n
   To test CApaDoor::NewL(), the method creates a process and adds a new document
   to app DLL using AddNewDocumentL(). Using the macro __UHEAP_SETFAIL() OOM
   scenario is simulated. Call CApaDoor::NewL() to observe the leave returned.\n\n
   To test CApaDoor::StoreL(), the method creates a process and adds a new 
   document to app DLL using AddNewDocumentL(). It calls CApaDoor::NewL() to
   create a wrapper for the document. A temporary buffer store is created.
   Now Use macro __UHEAP_SETFAIL() to simulate the OOM scenario.
   Call CApaDoor::StoreL() to store the document in the specified store.
   Observe the leave returned.\n\n
   To test CApaDoor::Restore(), the method creates a process and adds a new
   document to app DLL using AddNewDocumentL(). It calls CApaDoor::NewL()
   to create a wrapper for the document. A temporary buffer store is created.
   Now Call CApaDoor::StoreL() to store the document in the specified store.
   Use macro __UHEAP_SETFAIL() to simulate the OOM scenario. Call
   CApaDoor::RestoreL() to restore the document from the specified store.
   Observe the leave returned.\n
   API Calls:\n	
   CApaDoor::NewL(RFs& aFs, CApaDocument& aDoc,const TSize& aDefaultIconSizeInTwips)\n
   CApaDoor::StoreL(CStreamStore& aStore) const\n
   CApaDoor::RestoreL(const CStreamStore& aStore,TStreamId aHeadStreamId)\n
   
   @SYMTestExpectedResults Tests should complete without any memory leaks.
    
 */
void CT_OOMStep::TestDoorOOML()
	{
	CApaProcess* process=NULL;
	CApaDocument* doc=NULL;
	CApaDoor* door=NULL;
	TInt failRate=0;
	//
	INFO_PRINTF1(_L("CApaDoor construction under OOM"));
	//
	__UHEAP_MARK;
	//Create a session with F & B server
	TInt ret=RFbsSession::Connect();
		TEST(!ret);
	
	for (failRate=1;;failRate++)
		{
		__UHEAP_RESET;
		door = NULL;
		process = CApaProcess::NewL(iFs);
		TApaApplicationFactory appFact(KUidTestApp);
		doc=process->AddNewDocumentL(appFact);

		__UHEAP_SETFAIL(RHeap::EDeterministic,failRate);

		door = NULL;
		TRAPD(ret,door=CApaDoor::NewL(iFs,*doc,TSize(400,400)));
			TEST((ret==KErrNone || ret==KErrNoMemory));
		if (ret!=KErrNone)
			{
			delete process;
			TEST(door==NULL);
			}
		else
			{
			TEST(door!=NULL);
			delete door;

			delete process;
			break;
			}
		}
	__UHEAP_RESET;
	INFO_PRINTF2(_L("  #allocs for c'tion: %d\n"),failRate-1);
	//
	INFO_PRINTF1(_L("CApaDoor Store() under OOM"));
	//
	CBufStore* store=NULL;
	for (failRate=1;;failRate++)
		{
		__UHEAP_RESET;
		door = NULL;
		process = CApaProcess::NewL(iFs);	
		TApaApplicationFactory appFact(KUidTestApp);
		doc=process->AddNewDocumentL(appFact);	
		
		door = CApaDoor::NewL(iFs,*doc,TSize(400,400)); // owns doc
		store = CBufStore::NewL(10);
		__UHEAP_SETFAIL(RHeap::EDeterministic,failRate);

		TStreamId id=KNullStreamId;
		TRAPD(ret,id=door->StoreL(*store));
			TEST((ret==KErrNone || ret==KErrNoMemory));
		if (ret!=KErrNone)
			{
			TEST(id==KNullStreamId);
			delete store;
			delete door;

			delete process;
			}
		else
			{
			TEST(id!=KNullStreamId);
			delete store;

			delete door;
			delete process;
			break;
			}
		}
	__UHEAP_RESET;
	INFO_PRINTF2(_L("  #allocs: %d\n"),failRate-1);
	//
	INFO_PRINTF1(_L("CApaDoor Restore() under OOM"));
	//
	for (failRate=1;;failRate++)
		{
		__UHEAP_RESET;
		door = NULL;
		process = CApaProcess::NewL(iFs);
		TApaApplicationFactory appFact(KUidTestApp);
		doc = process->AddNewDocumentL(appFact);
		door = CApaDoor::NewL(iFs,*doc,TSize(400,400)); // owns doc
		store = CBufStore::NewL(10);
		TStreamId id = door->StoreL(*store);
		__UHEAP_SETFAIL(RHeap::EDeterministic,failRate);

		TRAPD(ret,door->RestoreL(*store,id));
			TEST((ret==KErrNone || ret==KErrNoMemory));
		if (ret!=KErrNone)
			{
			delete store;
			delete door;

			delete process;
			}
		else
			{
			delete store;
			delete door;

			delete process;
			break;
			}
		}
	__UHEAP_RESET;
	INFO_PRINTF2(_L("  #allocs: %d\n"),failRate-1);
	//
	//Close the session F & B server.
	RFbsSession::Disconnect();
	REComSession::FinalClose();
	__UHEAP_MARKEND;
	}


/**
  Auxiliary Fn for all Test Cases.
 
  This method creates and installs an active scheduler and puts the
  test code on the scheduler as a CIdle object. The method initiates
  all tests by calling the static method CT-OOMStepCallBack::CallBack().
 
*/
void CT_OOMStep::DoTestsInCallBackL()
	{
	// create an active scheduler
	CActiveScheduler* scheduler = new(ELeave) CActiveScheduler;
	CActiveScheduler::Install(scheduler);
	CleanupStack::PushL(scheduler);

	// put the test code onto the scheduler as an idle object
	CIdle* idle=CIdle::NewL(-20);
	CleanupStack::PushL(idle);

	CT_OOMStepCallBack* callBack = new(ELeave) CT_OOMStepCallBack(this);
	CleanupStack::PushL(callBack);

	idle->Start(TCallBack(CT_OOMStepCallBack::CallBack,callBack));
	// start the test code
	CActiveScheduler::Start();

	// all outstanding requests complete - kill the scheduler
	CleanupStack::PopAndDestroy(3); //scheduler, callBack, idle
	}



CT_OOMStepCallBack::CT_OOMStepCallBack(CT_OOMStep* aTestStep)
{
	iTestStep = aTestStep;
}


CT_OOMStepCallBack::~CT_OOMStepCallBack()
{

}
/**
  Auxiliary Fn for all Test Cases.
 
  The method initiates all tests to be performed.
 
*/
void CT_OOMStep::DoStepTests()
{
	__UHEAP_MARK;
	
	INFO_PRINTF1(_L("About to test OOM resilience"));
	TRAPD(r,TestOOMConstructionL());
		TEST(r==KErrNone);
	__UHEAP_MARKEND;
	
 	__UHEAP_MARK;
	INFO_PRINTF1(_L("About to test door OOM resilience"));
	TRAP(r,TestDoorOOML());
		TEST(r==KErrNone);
	__UHEAP_MARKEND;
}

TInt CT_OOMStepCallBack::CallBack(TAny* callBack/*aThis*/)
/**
  This static method is the callback function of CIdle object. The method
  calls the non-static method DoStepTests() which initiates all the tests. 
*/
	{

	//Do Tests.
	((CT_OOMStepCallBack *)callBack)->iTestStep->DoStepTests();

	CActiveScheduler::Stop();
	return EFalse; // don't call back again
	}




CT_OOMStep::~CT_OOMStep()
/**
   Destructor
 */
	{
	}

CT_OOMStep::CT_OOMStep()
/**
   Constructor
 */
	{
	// Call base class method to set up the human readable name for logging
	SetTestStepName(KT_OOMStep);
	}

TVerdict CT_OOMStep::doTestStepPreambleL()
/**
   @return - TVerdict code
   Override of base class virtual
 */
	{
	SetTestStepResult(EPass);
	return TestStepResult();
	}

TVerdict CT_OOMStep::doTestStepPostambleL()
/**
   @return - TVerdict code
   Override of base class virtual
 */
	{
	return TestStepResult();
	}

TVerdict CT_OOMStep::doTestStepL()
/**
  @return - TVerdict code
  Override of base class virtual
*/
{
	INFO_PRINTF1(_L("Testing Apparch...OOM tests"));
	//
	// set up an fbs
	FbsStartup();
	//
	// set up the directory structure
	iFs.Connect();
	setup();
	//
	// run the testcode

	TRAPD(ret,DoTestsInCallBackL())
		TEST(ret==KErrNone);
	
	iFs.Close();
	return TestStepResult();
}