// 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();
}