// 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:
// Example CTestStep derived implementation
//
/**
@file SELFStep.cpp
@internalTechnology
*/
#include "utracestep.h"
#include "tcoredumpserversuitedefs.h"
#include "tcoredumpserverSuiteServer.h"
#include <crashdatasave.h>
#include <s32file.h>
#include <e32property.h>
CUTraceStep::~CUTraceStep()
/**
* Destructor
*/
{
}
CUTraceStep::CUTraceStep()
/**
* Constructor
*/
{
// **MUST** call SetTestStepName in the constructor as the controlling
// framework uses the test step name immediately following construction to set
// up the step's unique logging ID.
SetTestStepName (KUTraceUserSide);
}
TVerdict CUTraceStep::doTestStepPreambleL()
/**
* @return - TVerdict code
* Override of base class virtual
*/
{
TInt ret = KErrNone;
ret = iSess.Connect ();
if ( ret != KErrNone)
{
SetTestStepResult ( EFail);
INFO_PRINTF2 (_L ("Error %d from iSess->Connect()/n"), ret);
}
else
{
SetTestStepResult (EPass);
}
ret = iFs.Connect ();
if ( ret != KErrNone)
{
SetTestStepResult ( EFail);
INFO_PRINTF2 (_L ("Error %d from iFs->Connect()/n"), ret);
}
else
{
SetTestStepResult (EPass);
}
return TestStepResult ();
}
void CUTraceStep::ClientAppL()
/**
* @return void
* This calls each stage of the test
*/
{
INFO_PRINTF1 (_L ("Starting UTrace User Side Test Suite"));
TestTraceDataL ();
}
void CUTraceStep::TestTraceDataL()
{
_LIT (KCrashFileName, "c:\\trace");
HandleCrashL (KCrashFileName);
}
void CUTraceStep::HandleCrashL(const TDesC& aFileName)
/**
* @return void
* Tests handling a crash
*/
{
if ( TestStepResult ()==EPass)
{
_LIT (KCrashAppParam, "-d1 -t");
INFO_PRINTF3 (_L ("The CrashApp Param is %S, The Filename is is %S"),
&KCrashAppParam, &aFileName);
//Start the process that we intend to crash....
RProcess crashProcess;
CleanupClosePushL (crashProcess);
TInt ret = crashProcess.Create ( KCrashAppFileName, KCrashAppParam);
if ( ret != KErrNone)
{
INFO_PRINTF2 (
_L ("Error %d from RProcess.Create(z:\\sys\\bin\\crashapp.exe)/n"),
ret);
SetTestStepResult (EFail);
User::Leave (ret);
}
LoadUTraceFormatterL ();
LoadFileWriterL ();
//configure cds and writer
_LIT ( KFilePathPrompt, "not_important");
INFO_PRINTF1 (_L ("Configuring CDS"));
DoConfigureL (2, CDS_UID.iUid, COptionConfig::ECoreDumpServer,
COptionConfig::ETUInt, KPostCrashEventActionPrompt, 1,
KNullDesC, 4, KNullDesC, 0);
INFO_PRINTF1 (_L ("Configuring File Writer"));
DoConfigureL ((TInt)(CCrashDataSave::ECoreFilePath), WRITER_UID.iUid,
COptionConfig::EWriterPlugin, COptionConfig::ETFileName,
KFilePathPrompt, 1, KNullDesC, 0, aFileName, 0);
// Observe the process and wait for a crash
INFO_PRINTF1 (_L ("Observing bad boy crash app"));
TRAP (ret, iSess.ObservationRequestL ( KCrashAppFileName,
KCrashAppFileName, ETrue));
if ( ret != KErrNone)
{
INFO_PRINTF2 (
_L ("Error %d iSess.ObservationRequestL(z:\\sys\\bin\\crashapp.exe)\n"),
ret);
SetTestStepResult (EFail);
User::Leave ( ret);
}
//start the crash process
crashProcess.Resume ();
CleanupStack::PopAndDestroy (&crashProcess); //this is for crashProcess
//Monitor the progress of the crash file being generated...
MonitorProgressL ();
User::After (5000000);
//Check dump has been generated...and valid
CDir *fileList = NULL;
TFindFile fileFinder(iFs);
TRAP (ret, fileList = CTe_coredumpserverSuite::DoesFileExistL (
aFileName, fileFinder));
if ( (ret != KErrNone) || (fileList == NULL))
{
INFO_PRINTF2 (_L ("Expected crash file was not generated: %d"),
ret);
SetTestStepResult (EFail);
User::Leave ( ret);
}
CleanupStack::PushL (fileList);
for (TInt i = 0; i < fileList->Count (); i++)
{
TParse fullName;
fullName.Set ((*fileList)[i].iName, &fileFinder.File(), NULL);
VerifyTraceDataL (fullName.FullName ());
INFO_PRINTF2 (_L ("Deleting %S"), &fullName.FullName ());
User::LeaveIfError (iFs.Delete (fullName.FullName ()));
}
CleanupStack::PopAndDestroy (fileList);
INFO_PRINTF1 (_L ("Expected trace crash file was generated and parsed successfully"));
}
}
void CUTraceStep::MonitorProgressL()
{
RProperty crashProgress;
User::LeaveIfError (crashProgress.Attach (KCoreDumpServUid, ECrashProgress));
TBuf<50> crashProg;
TRequestStatus status;
crashProgress.Subscribe (status);
User::WaitForRequest (status);
//Subscribe for next one again...
crashProgress.Subscribe (status);
//First one should be the start string = "-"
User::LeaveIfError (crashProgress.Get (crashProg));
if ( crashProg != KStartOfUTraceProc)
{
INFO_PRINTF1 (_L ("UTRACE formatter has not started processing the data"));
}
INFO_PRINTF1 (_L ("UTRACE formatter has started processing the data"));
INFO_PRINTF1 (_L ("Waiting to be notified of the timeout of the processing. A timeout here is a fail"));
//Now we wait until its finished
do
{
User::WaitForRequest (status);
crashProgress.Subscribe (status);
User::LeaveIfError (crashProgress.Get (crashProg));
}
while (crashProg != KEndOfProcessing);
INFO_PRINTF1 (_L ("UTRACE formatter has finished processing the data"));
}
void CUTraceStep::DoConfigureL(const TUint32& aIndex, const TUint32& aUID,
const COptionConfig::TParameterSource& aSource,
const COptionConfig::TOptionType& aType, const TDesC& aPrompt,
const TUint32& aNumOptions, const TDesC& aOptions, const TInt32& aVal,
const TDesC& aStrValue, const TUint aInstance)
/**
* @return void
* @param aIndex Internal index to the component that owns the object
* @param aUID UID of the component that owns the object
* @param aSource Type of component that owns the object
* @param aType Type of parameter
* @param aPrompt Prompt to present to user
* @param aNumOptions Number of options that the parameter can be set to. Only applies if type is ETMultiEntryEnum.
* @param aOptions Comma separated list of options. Applies to ETMultiEntryEnum and ETBool
* @param aVal Integer value. Applies to ETInt, ETUInt, ETBool
* @param aStrValue String value. Applies to ETString, ETFileName, ETMultiEntry, ETBool
*/
{
COptionConfig * config;
config = COptionConfig::NewL ( aIndex, aUID, aSource, aType, aPrompt,
aNumOptions, aOptions, aVal, aStrValue);
CleanupStack::PushL (config);
config->Instance (aInstance);
//Configure now...
TRAPD (ret, iSess.SetConfigParameterL (*config));
if ( ret != KErrNone)
{
INFO_PRINTF2 (_L ("Error %d changing param/n"), ret);
SetTestStepResult (EFail);
User::Leave (ret);
}
CleanupStack::PopAndDestroy (config);
}
void CUTraceStep::LoadUTraceFormatterL()
/**
* @return void
* Utility function to load the UTRACE formatter
*/
{
INFO_PRINTF1 (_L ("Attempting to load UTRACE Plugin"));
TPluginRequest req;
req.iPluginType = TPluginRequest::EFormatter;
req.iLoad = ETrue;
req.iUid = UTRACE_UID;
// Should be allowed to load utrace formatter
TRAPD (ret, iSess.PluginRequestL ( req));
if ( ret != KErrNone)
{
ERR_PRINTF2 (_L ("Failed to load writer plugin, error = %d"), ret);
SetTestStepResult (EFail);
User::Leave (ret);
}
}
void CUTraceStep::LoadFileWriterL()
{
TPluginRequest req;
TUid writerUid = WRITER_UID;
req.iUid = writerUid;
req.iPluginType = TPluginRequest::EWriter;
req.iLoad = ETrue;
TRAPD (ret, iSess.PluginRequestL ( req));
if ( ret != KErrNone)
{
ERR_PRINTF2 (_L ("Failed to load writer plugin, error = %d"), ret);
SetTestStepResult (EFail);
User::Leave (ret);
}
}
TVerdict CUTraceStep::doTestStepL()
/**
* @return - TVerdict code
* Override of base class pure virtual
* Our implementation only gets called if the base class doTestStepPreambleL() did
* not leave. That being the case, the current test result value will be EPass.
*/
{
if ( TestStepResult ()==EPass)
{
TInt ret = KErrNone;
__UHEAP_MARK;
TRAP (ret, ClientAppL ());
if ( KErrNone != ret)
{
SetTestStepResult (EFail);
INFO_PRINTF2 (
_L ("Error %d from CTestFormatterUserSideStep->ClientAppL()"),
ret);
}
__UHEAP_MARKEND;
}
return TestStepResult ();
}
TVerdict CUTraceStep::doTestStepPostambleL()
/**
* @return - TVerdict code
* Override of base class virtual
*/
{
iSess.Disconnect ();
User::After (10000000); //ensure we give enough time for session to close
iFs.Close ();
return EPass;
}
void CUTraceStep::VerifyTraceDataL(const TDesC& aFullFilename)
{
INFO_PRINTF2 (_L ("VerifyTraceDataL (Not Implemented) The Filename is is %S"),
&aFullFilename);
}