// Copyright (c) 2007-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:
//
/**
@file
@test
@internalComponent - Internal Symbian test code
*/
#include <startupproperties.h>
#include "startsafe.h"
#include "testapps.h"
#include "tstartsafe_procfailsysrestart.h"
#include "tpowerdownclient.h"
CAppFwkStartSafeTestStepProcFailSysRestart::CAppFwkStartSafeTestStepProcFailSysRestart()
{
SetTestStepName(KCTestCaseProcFailSysRestart);
}
CAppFwkStartSafeTestStepProcFailSysRestart::~CAppFwkStartSafeTestStepProcFailSysRestart()
{
delete iNotifier;
}
static TInt StartApplication(TAny* aSelf)
{
CTrapCleanup* cleanup=CTrapCleanup::New();
TInt r=KErrNoMemory;
if (cleanup)
{
CAppFwkStartSafeTestStepProcFailSysRestart* self = (CAppFwkStartSafeTestStepProcFailSysRestart*)aSelf;
TRAP(r, self->DoStartApplicationL());
delete cleanup;
}
return r;
}
/**
Old Test CaseID APPFWK-STARTSAFE-0013
New Test CaseID DEVSRVS-SYSSTART-STARTSAFE-0013
*/
TVerdict CAppFwkStartSafeTestStepProcFailSysRestart::doTestStepL()
{
#ifdef __WINSCW__
ASSERT(0);
#endif
//create scheduler
//create savenotifier
CActiveScheduler* sched = new(ELeave) CActiveScheduler;
CleanupStack::PushL(sched);
CActiveScheduler::Install(sched);
iNotifier = CSaveNotifier::NewL(*this);
//Create a new thread and resume it
RThread thread;
CleanupClosePushL(thread);
User::LeaveIfError(thread.Create(_L("StarterThread"), StartApplication, KDefaultStackSize, NULL, this));
TRequestStatus stat;
thread.Rendezvous(stat);
if (stat!=KRequestPending)
{
thread.Kill(0); // abort startup
TEST(EFalse); // fail test
return TestStepResult();
}
else
{
thread.Resume(); // logon OK - run DoStartApplicationL
}
User::WaitForRequest(stat); // wait for rendevouz
//Some sanity checks to verify our new thread is healthy
TInt r=(thread.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
CleanupStack::PopAndDestroy(&thread); //only this handle
User::LeaveIfError(r);
iShutdownInitiated.UniversalTime();
INFO_PRINTF1( _L("Attempt to start the failing Test Application will cause an OS Restart") );
INFO_PRINTF4( _L("StartL called at time %d:%d.%d"), iShutdownInitiated.DateTime().Minute(), iShutdownInitiated.DateTime().Second(), iShutdownInitiated.DateTime().MicroSecond());
INFO_PRINTF1(_L("Starting scheduler"));
CActiveScheduler::Start(); //Wait for MSaveObserver callback
//resume here after callback has stopped the scheduler
INFO_PRINTF2( _L("Asserting that the shutdown was at all initiated: %d"), iCallbackReceived );
TESTE(iCallbackReceived, iCallbackReceived);
//assert the thread calling StartL is still blocked
TESTE(KErrNone == iStartSafeError, iStartSafeError);
if(iCallbackReceived)
{
const TTimeIntervalMicroSeconds elapsedTime = iShutdownPerformed.MicroSecondsFrom(iShutdownInitiated);
const TDateTime dt = iShutdownPerformed.DateTime();
const TInt64 value = elapsedTime.Int64();
INFO_PRINTF5(_L("Shutdown callback received at time %d:%d.%d (after %d microseconds)"), dt.Minute(), dt.Second(), dt.MicroSecond(), value);
TESTE((value >= 0) && (value < 1000000), value); // within 1 second
// Now call CPowerdownClient::QueryServerPowerState() which will in turn call the method 'ServerPowerState()'
// to stop the shutdown. This function call will cause the shutdown server in syslibs/pwrcli to cancel power off.
INFO_PRINTF1(_L("Aborting shutdown sequence"));
TBool powerOff = EFalse;
CPowerdownClient* powerdownclient = CPowerdownClient::NewL();
CleanupStack::PushL(powerdownclient);
TEST(KErrNone == powerdownclient->QueryServerPowerState(iNotifier,powerOff));
TEST(powerOff);
CleanupStack::PopAndDestroy(powerdownclient);
CleanupStack::PopAndDestroy(sched);
}
else
{
TEST(EFalse);
}
return TestStepResult();
}
void CAppFwkStartSafeTestStepProcFailSysRestart::DoStartApplicationL()
{
// warning: the Tef framework can't do logging from this thread
CStartSafe* startSafe = CStartSafe::NewL();
CleanupStack::PushL( startSafe );
CStartupProperties* prop = CStartupProperties::NewLC(KTestAppNoRv, KNullDesC);
prop->SetStartupType( EStartApp );
prop->SetStartMethod( EWaitForStart );
prop->SetTimeout( 1 );
prop->SetNoOfRetries( 0 );
prop->SetRecoveryParams( ERestartOS, 0 );
TInt tried = 0;
RProcess proc;
// We are expecting StartL to leave because KTestAppNoRv will fail to start, so any items
// on the CleanupStack would be deleted/closed on this call.
CleanupStack::Pop(2, startSafe);
RThread::Rendezvous(KErrNone);
TRAP( iStartSafeError, startSafe->StartL(*prop, proc, tried) ); // Will initiate ERestartOS and then freeze this thread for 5 seconds
proc.Close();
delete prop;
delete startSafe;
}
/**
Called by the shutdown server in syslib/pwrcli when device is initiating a shut down.
*/
void CAppFwkStartSafeTestStepProcFailSysRestart::SaveL(TSaveType /*aSaveType*/)
{
// Do assertions in the doTestStepL function, just save values for now
iCallbackReceived = ETrue;
iShutdownPerformed.UniversalTime();
iNotifier->DelayRequeue();
CActiveScheduler::Stop();
}