diff -r 000000000000 -r 4e1aa6a622a0 resourcemgmt/powerandmemorynotificationservice/tsrc/t_pwrbasic.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resourcemgmt/powerandmemorynotificationservice/tsrc/t_pwrbasic.cpp Tue Feb 02 00:53:00 2010 +0200 @@ -0,0 +1,468 @@ +// Copyright (c) 2004-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: +// This test will be able to do what it is planned to do only if the shutdown client and server +// components are built with SYSLIBS_TEST macro defined. +// +// + +#include //RTest +#include //RDebug +#include //RSaveSession, MSaveObserver, CSaveNotifier + +static RTest TheTest(_L("T_PwrBasic")); +const TInt KOneSec = 1000000; +_LIT(KTestFailed, "Invalid Test Step %d\n"); + +// The timeout of 2 seconds which is longer than the one defined at server side(1.5 seconds). +// It triggers events after CServShutdownServer::SwitchOff() has been called. +const TUint32 KShtdwnTimeoutLonger =2000000; + +// The timeout of 1 second which is shorter than the one defined at server side(1.5 seconds). +// It triggers events before CServShutdownServer::SwitchOff() has been called. +const TUint32 KShtdwnTimeoutShorter =1000000; + +// +// +//Test macroses and functions +static void Check(TInt aValue, TInt aLine) + { + if(!aValue) + { + TheTest(EFalse, aLine); + } + } +static void Check(TInt aValue, TInt aExpected, TInt aLine) + { + if(aValue != aExpected) + { + RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); + TheTest(EFalse, aLine); + } + } +#define TEST(arg) ::Check((arg), __LINE__) +#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__) + +// + +static void Leave(TInt aLine, TInt aError) + { + RDebug::Print(_L("*** Leave. Error: %d, line: %d\r\n"), aError, aLine); + User::Leave(aError); + } +static void LeaveIfError(TInt aLine, TInt aError) + { + if(aError < KErrNone) + { + ::Leave(aLine, aError); + } + } +static void LeaveIfNull(TInt aLine, TAny* aPtr) + { + if(!aPtr) + { + ::Leave(aLine, KErrNoMemory); + } + } +#define __LEAVE(err) ::Leave(__LINE__, err) +#define __LEAVE_IF_ERROR(err) ::LeaveIfError(__LINE__, err) +#define __LEAVE_IF_NULL(ptr) ::LeaveIfNull(__LINE__, ptr) + +// +// +//Test classes & objects + +//This test class is used to receive a powerdown notification from the shutdown server. +class CPowerdownClient : public CActive, public MSaveObserver + { +public: + static CPowerdownClient* NewLC(); + virtual ~CPowerdownClient(); + virtual void SaveL(MSaveObserver::TSaveType aSaveType); + +protected: + virtual void DoCancel(); + virtual void RunL(); + +private: + CPowerdownClient(); + void ConstructL(); + +private: + RTimer iTimer; + CSaveNotifier* iSaveNotifier; + + }; + +CPowerdownClient* CPowerdownClient::NewLC() + { + CPowerdownClient* self = new CPowerdownClient; + __LEAVE_IF_NULL(self); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CPowerdownClient::~CPowerdownClient() + { + Cancel(); + iTimer.Close(); + delete iSaveNotifier; + } + +//MSaveNotifier::SaveL() implementation. Called when powerdown event occurs. +void CPowerdownClient::SaveL(MSaveObserver::TSaveType) + { + iSaveNotifier->DelayRequeue(); + + iTimer.After(iStatus, KOneSec); + TEST2(iStatus.Int(), KRequestPending); + SetActive(); + } + +void CPowerdownClient::DoCancel() + { + iTimer.Cancel(); + } + +//Processes timer events. +void CPowerdownClient::RunL() + { + static TBool powerOffCalled = EFalse; + if(!powerOffCalled) + { + TEST2(iSaveNotifier->SwitchOff(MSaveObserver::ESaveAll, ETrue), KErrNone); + powerOffCalled = ETrue; + } + else + { + iSaveNotifier->HandleError(KErrGeneral); + User::After(KOneSec); + CActiveScheduler::Stop(); + } + } + +//Adds the CPowerdownClient object to the active scheduler. +CPowerdownClient::CPowerdownClient() : + CActive(CActive::EPriorityStandard) + { + CActiveScheduler::Add(this); + } + +//Constructs CPowerdownClient object and generates a timer event, processed 1 second later. +void CPowerdownClient::ConstructL() + { + iSaveNotifier = CSaveNotifier::NewL(*this); + __LEAVE_IF_ERROR(iTimer.CreateLocal()); + iTimer.After(iStatus, KOneSec); + TEST2(iStatus.Int(), KRequestPending); + SetActive(); + } +/** + DEF048920 - PwrCli server may panic if CSaveNotifier::HandleError() is called from... + What the test does is: + 1) The test creates a CPowerdownClient object. + 2) CPowerdownClient object will raise a timer event, which will be processed after 1 second. + 3) The test starts the scheduler. + 4) The timer event gets processed in CPowerdownClient::RunL() - it initiates a powerdown + sequence. + 5) The shutdown server will notify the client (CPowerdownClient), calling + CPowerdownClient::SaveL() method. + 6) CPowerdownClient::SaveL() will call CSaveNotifier::DelayRequeue() not to re-register itself. + Then it will raise a timer event, which will be processed after 1 second. + 7) The second timer event gets processed in CPowerdownClient::RunL() - it calls + CSaveNotifier::HandleError(). + Without the fix CSaveNotifier::HandleError() causes "BadHandle" panic on the server side. + +@SYMTestCaseID SYSLIB-PWRLCLI-CT-3686 +@SYMTestCaseDesc Tests for defect number DEF048920 +@SYMTestPriority High +@SYMTestActions Initiate a powerdown sequence.The shutdown server will notify the client,which delays the + power off and then raises a timer event which stops the scheduler +@SYMTestExpectedResults Test must not fail +@SYMREQ REQ0000 +*/ +void DEF048920L() + { + CActiveScheduler* scheduler = new CActiveScheduler; + __LEAVE_IF_NULL(scheduler); + CleanupStack::PushL(scheduler); + CActiveScheduler::Install(scheduler); + + CPowerdownClient* powerdownClient = CPowerdownClient::NewLC(); + + CActiveScheduler::Start(); + + CleanupStack::PopAndDestroy(powerdownClient); + CleanupStack::PopAndDestroy(scheduler); + } + + + +// This test class is used to receive a powerdown notification from the shutdown server. +// Its SaveL() calls MSaveObserver::DelayRequeue() not to re-register itself. Its RunL() may call +// CSaveNotifier::HandleError() to send error to the server. But both behaviors will not stop the server's +// shutdown execution. +class CPowerdownClient2 : public CActive, public MSaveObserver + { +public: + static CPowerdownClient2* NewLC(); + virtual ~CPowerdownClient2(); + virtual void SaveL(MSaveObserver::TSaveType aSaveType); + +protected: + virtual void DoCancel(); + virtual void RunL(); + +private: + CPowerdownClient2(); + void ConstructL(); + +private: + enum TTestSteps + { + TRequestSwitchOff1, + TClientSave1, + TClientCheckServerPowerOff1, + TRequestSwitchOff2, + TClientSave2, + TClientSendError, + TClientCheckServerPowerOff2, + TTestStepEnd, + }; + +private: + RTimer iTimer; + CSaveNotifier* iSaveNotifier; + TTestSteps iTestStep; + }; + +CPowerdownClient2* CPowerdownClient2::NewLC() + { + CPowerdownClient2* self = new CPowerdownClient2(); + __LEAVE_IF_NULL(self); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +CPowerdownClient2::~CPowerdownClient2() + { + Cancel(); + iTimer.Close(); + delete iSaveNotifier; + } + +//MSaveNotifier::SaveL() implementation. Called when powerdown event occurs. +void CPowerdownClient2::SaveL(MSaveObserver::TSaveType) + { + __ASSERT_ALWAYS(iTestStep == TClientSave1 || iTestStep == TClientSave2, \ + TheTest.Panic(KErrNotSupported, KTestFailed, iTestStep)); + + TBool powerOff = EFalse; + + // Checks the power state of the server. It should be off because the server has received + // the power off request. + // Calls DelayRequeue() not to re-register itself. + // Starts a timer which is longer than the server's shutdown timer. + // Move to next test step + if(iTestStep == TClientSave1) + { + iSaveNotifier->ServerPowerState(powerOff); + TEST(powerOff); + iSaveNotifier->DelayRequeue(); + iTestStep = TClientCheckServerPowerOff1; + iTimer.After(iStatus, KShtdwnTimeoutLonger); + TEST2(iStatus.Int(), KRequestPending); + SetActive(); + } + + // Checks the power state of the server. It should be off because the server has received + // the power off request. + // Calls DelayRequeue() not to re-register itself. + // Starts a timer which is shorter than the server's shutdown timer. + // Move to next test step + if(iTestStep == TClientSave2) + { + iSaveNotifier->ServerPowerState(powerOff); + TEST(powerOff); + iSaveNotifier->DelayRequeue(); + iTestStep = TClientSendError; + iTimer.After(iStatus, KShtdwnTimeoutShorter); + TEST2(iStatus.Int(), KRequestPending); + SetActive(); + } + } + +void CPowerdownClient2::DoCancel() + { + iTimer.Cancel(); + } + +//Processes timer events. +void CPowerdownClient2::RunL() + { + __ASSERT_ALWAYS(iTestStep == TRequestSwitchOff1 || iTestStep == TClientCheckServerPowerOff1 ||\ + iTestStep == TClientSendError, TheTest.Panic(KErrNotSupported, KTestFailed, iTestStep)); + + TBool powerOff = ETrue; + + // Requests server for switchoff for the first time + if(iTestStep == TRequestSwitchOff1) + { + TEST2(iSaveNotifier->SwitchOff(MSaveObserver::ESaveAll, ETrue), KErrNone); + iTestStep = TClientSave1; + } + + // Checks the power state of the server. It should be on because CServShutdownServer::SwitchOff() + // has been called. + // Requests server for switchoff for the second time. + if(iTestStep == TClientCheckServerPowerOff1) + { + iSaveNotifier->ServerPowerState(powerOff); + TEST(!powerOff); + iSaveNotifier->Queue(); // client re-register after the system resumes. + iTestStep = TRequestSwitchOff2; + User::After(KOneSec); + iTestStep = TClientSave2; + TEST2(iSaveNotifier->SwitchOff(MSaveObserver::ESaveAll, ETrue), KErrNone); + } + + // Checks the power state of the server. It should be off because CServShutdownServer::SwitchOff() + // has not been called. + // Sends error to server. The server will ignore the error message. + // HandleError re-registers the client thus triggers the CServShutdownServer::SwitchOff(). + // Checks the power state of the server again. It should be on because CServShutdownServer::SwitchOff() + // has been called. + // Stops the active scheduler. + if(iTestStep == TClientSendError) + { + iSaveNotifier->ServerPowerState(powerOff); + TEST(powerOff); + iSaveNotifier->HandleError(KErrGeneral); + iTestStep = TClientCheckServerPowerOff2; + User::After(KOneSec); + iSaveNotifier->ServerPowerState(powerOff); + TEST(!powerOff); + iTestStep = TTestStepEnd; + CActiveScheduler::Stop(); + } + } + +//Adds the CPowerdownClient2 object to the active scheduler. +CPowerdownClient2::CPowerdownClient2() : + CActive(CActive::EPriorityStandard), iTestStep(TRequestSwitchOff1) + { + CActiveScheduler::Add(this); + } + +//Constructs CPowerdownClient2 object and generates a timer event, processed 1 second later. +void CPowerdownClient2::ConstructL() + { + iSaveNotifier = CSaveNotifier::NewL(*this); + __LEAVE_IF_ERROR(iTimer.CreateLocal()); + iTimer.After(iStatus, KOneSec); + TEST2(iStatus.Int(), KRequestPending); + SetActive(); + } + + +/** + DEF111025 - Device restarts from PREQ1089 UIF functionality can be delayed indefinitely. + What this test does is: + 1) The test creates a CPowerdownClient2 object, which raises a 1-second timer event. The test starts + the scheduler. + 2) The timer event gets processed in CPowerdownClient2::RunL() - it initiates a powerdown + sequence. + 3) The shutdown server notifies the client (CPowerdownClient2), calling CPowerdownClient2::SaveL() + method. + 4) CPowerdownClient2::SaveL() gets the power state of the server and checks whether it is off to ensure + the server has received the shutdown request but not executed CServShutdownServer::SwitchOff() yet. + It calls CSaveNotifier::DelayRequeue() not to re-register itself. + Then it raises a timer, which is longer than the shutdown timer defined at the server side. + 5) The timer event gets processed in CPowerdownClient::RunL(). It gets the power state of the server + and checks whether it is on to ensure the server has had CServShutdownServer::SwitchOff() executed by + the shutdown timer. + Then it initiates a powerdown sequence for the second time. + 6) The shutdown server notifies the client (CPowerdownClient2), calling CPowerdownClient2::SaveL() + method. + 7) CPowerdownClient2::SaveL() gets the power state of the server and checks whether it is off to ensure + the server has received the shutdown request but not executed CServShutdownServer::SwitchOff() yet. + It calls CSaveNotifier::DelayRequeue() not to re-register itself. + Then it raises a timer, which is shorter than the shutdown timer defined at the server side. + 8) The timer event gets processed in CPowerdownClient::RunL(). It gets the power state of the server + and checks whether it is off to ensure the server still has not executed CServShutdownServer::SwitchOff(). + It calls CSaveNotifier::HandleError() to send an error to the server. After sometime, It gets the power + state of the server again and checks whether it is on to ensure the server has had + CServShutdownServer::SwitchOff() executed by the shutdown timer. + Then it stops the active scheduler. + + Without the fix the checking of power state of the server would fail in a certain step. + +@SYMTestCaseID SYSLIB-PWRCLI-CT-4001 +@SYMTestCaseDesc Tests for defect number DEF111025 +@SYMTestPriority High +@SYMTestActions Initiates a powerdown sequence which sends 2 poweroff requests to server. The shutdown + server will notify the client twice. The first time when being notified, the client will + not re-register itself. For the second time, it will send error to the server. During + this procedure, some checkpoints will be set to check the power states of the server. +@SYMTestExpectedResults The test program should not panic or leave. At power state checkpoints, the power states + queried from the server should be the expected values. +@SYMDEF DEF111025 +*/ +void DEF111025L() + { + CActiveScheduler* scheduler = new CActiveScheduler; + __LEAVE_IF_NULL(scheduler); + CleanupStack::PushL(scheduler); + CActiveScheduler::Install(scheduler); + + CPowerdownClient2* powerdownClientTimer = CPowerdownClient2::NewLC(); + + CActiveScheduler::Start(); + CleanupStack::PopAndDestroy(powerdownClientTimer); + CleanupStack::PopAndDestroy(scheduler); + } +// +// +//Tests + +static void DoRunL() + { + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-PWRLCLI-CT-3686 DEF048920 ")); + ::DEF048920L(); + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-PWRCLI-CT-4001 DEF111025 ")); + ::DEF111025L(); + } + +TInt E32Main() + { + __UHEAP_MARK; + CTrapCleanup* tc = CTrapCleanup::New(); + TEST(tc != NULL); + + TheTest.Start(_L("Power shutdown tests")); + + TRAPD(err, ::DoRunL()); + TEST2(err, KErrNone); + + TheTest.End(); + TheTest.Close(); + + delete tc; + + __UHEAP_MARKEND; + + User::Heap().Check(); + return KErrNone; + }