resourcemgmt/powerandmemorynotificationservice/tsrc/t_pwrbasic.cpp
changeset 0 4e1aa6a622a0
child 48 86cf7a1b7eb9
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This test will be able to do what it is planned to do only if the shutdown client and server
       
    15 // components are built with SYSLIBS_TEST macro defined.
       
    16 // 
       
    17 //
       
    18 
       
    19 #include <e32test.h>        //RTest
       
    20 #include <e32svr.h>         //RDebug
       
    21 #include <savenotf.h>       //RSaveSession, MSaveObserver, CSaveNotifier
       
    22 
       
    23 static RTest TheTest(_L("T_PwrBasic"));
       
    24 const TInt KOneSec = 1000000;
       
    25 _LIT(KTestFailed, "Invalid Test Step %d\n");
       
    26 
       
    27 // The timeout of 2 seconds which is longer than the one defined at server side(1.5 seconds).
       
    28 // It triggers events after CServShutdownServer::SwitchOff() has been called.
       
    29 const TUint32 KShtdwnTimeoutLonger =2000000;
       
    30 
       
    31 // The timeout of 1 second which is shorter than the one defined at server side(1.5 seconds).
       
    32 // It triggers events before CServShutdownServer::SwitchOff() has been called.
       
    33 const TUint32 KShtdwnTimeoutShorter =1000000;
       
    34 
       
    35 //
       
    36 //
       
    37 //Test macroses and functions
       
    38 static void Check(TInt aValue, TInt aLine)
       
    39 	{
       
    40 	if(!aValue)
       
    41 		{
       
    42 		TheTest(EFalse, aLine);
       
    43 		}
       
    44 	}
       
    45 static void Check(TInt aValue, TInt aExpected, TInt aLine)
       
    46 	{
       
    47 	if(aValue != aExpected)
       
    48 		{
       
    49 		RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
       
    50 		TheTest(EFalse, aLine);
       
    51 		}
       
    52 	}
       
    53 #define TEST(arg) ::Check((arg), __LINE__)
       
    54 #define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
       
    55 
       
    56 //
       
    57 
       
    58 static void Leave(TInt aLine, TInt aError)
       
    59 	{
       
    60 	RDebug::Print(_L("*** Leave. Error: %d, line: %d\r\n"), aError, aLine);
       
    61 	User::Leave(aError);
       
    62 	}
       
    63 static void LeaveIfError(TInt aLine, TInt aError)
       
    64 	{
       
    65 	if(aError < KErrNone)
       
    66 		{
       
    67 		::Leave(aLine, aError);
       
    68 		}
       
    69 	}
       
    70 static void LeaveIfNull(TInt aLine, TAny* aPtr)
       
    71 	{
       
    72 	if(!aPtr)
       
    73 		{
       
    74 		::Leave(aLine, KErrNoMemory);
       
    75 		}
       
    76 	}
       
    77 #define __LEAVE(err) ::Leave(__LINE__, err)
       
    78 #define __LEAVE_IF_ERROR(err) ::LeaveIfError(__LINE__, err)
       
    79 #define __LEAVE_IF_NULL(ptr) ::LeaveIfNull(__LINE__, ptr)
       
    80 
       
    81 //
       
    82 //
       
    83 //Test classes & objects
       
    84 
       
    85 //This test class is used to receive a powerdown notification from the shutdown server.
       
    86 class CPowerdownClient : public CActive, public MSaveObserver
       
    87     {
       
    88 public:
       
    89     static CPowerdownClient* NewLC();
       
    90     virtual ~CPowerdownClient();
       
    91     virtual void SaveL(MSaveObserver::TSaveType aSaveType);
       
    92 
       
    93 protected:
       
    94 	virtual void DoCancel();
       
    95 	virtual void RunL();
       
    96 
       
    97 private:
       
    98     CPowerdownClient();
       
    99     void ConstructL();
       
   100 
       
   101 private:
       
   102     RTimer iTimer;
       
   103     CSaveNotifier* iSaveNotifier;
       
   104 
       
   105     };
       
   106 
       
   107 CPowerdownClient* CPowerdownClient::NewLC()
       
   108     {
       
   109     CPowerdownClient* self = new CPowerdownClient;
       
   110     __LEAVE_IF_NULL(self);
       
   111     CleanupStack::PushL(self);
       
   112     self->ConstructL();
       
   113     return self;
       
   114     }
       
   115 
       
   116 CPowerdownClient::~CPowerdownClient()
       
   117     {
       
   118     Cancel();
       
   119     iTimer.Close();
       
   120     delete iSaveNotifier;
       
   121     }
       
   122 
       
   123 //MSaveNotifier::SaveL() implementation. Called when powerdown event occurs.
       
   124 void CPowerdownClient::SaveL(MSaveObserver::TSaveType)
       
   125     {
       
   126     iSaveNotifier->DelayRequeue();
       
   127 
       
   128     iTimer.After(iStatus, KOneSec);
       
   129     TEST2(iStatus.Int(), KRequestPending);
       
   130     SetActive();
       
   131     }
       
   132 
       
   133 void CPowerdownClient::DoCancel()
       
   134     {
       
   135     iTimer.Cancel();
       
   136     }
       
   137 
       
   138 //Processes timer events.
       
   139 void CPowerdownClient::RunL()
       
   140     {
       
   141     static TBool powerOffCalled = EFalse;
       
   142     if(!powerOffCalled)
       
   143         {
       
   144         TEST2(iSaveNotifier->SwitchOff(MSaveObserver::ESaveAll, ETrue), KErrNone);
       
   145         powerOffCalled = ETrue;
       
   146         }
       
   147     else
       
   148         {
       
   149         iSaveNotifier->HandleError(KErrGeneral);
       
   150         User::After(KOneSec);
       
   151         CActiveScheduler::Stop();
       
   152         }
       
   153     }
       
   154 
       
   155 //Adds the CPowerdownClient object to the active scheduler.
       
   156 CPowerdownClient::CPowerdownClient() :
       
   157     CActive(CActive::EPriorityStandard)
       
   158     {
       
   159 	CActiveScheduler::Add(this);
       
   160     }
       
   161 
       
   162 //Constructs CPowerdownClient object and generates a timer event, processed 1 second later.
       
   163 void CPowerdownClient::ConstructL()
       
   164     {
       
   165     iSaveNotifier = CSaveNotifier::NewL(*this);
       
   166     __LEAVE_IF_ERROR(iTimer.CreateLocal());
       
   167     iTimer.After(iStatus, KOneSec);
       
   168     TEST2(iStatus.Int(), KRequestPending);
       
   169     SetActive();
       
   170     }
       
   171 /**
       
   172   DEF048920 - PwrCli server may panic if CSaveNotifier::HandleError() is called from...
       
   173   What the test does is:
       
   174   1) The test creates a CPowerdownClient object.
       
   175   2) CPowerdownClient object will raise a timer event, which will be processed after 1 second.
       
   176   3) The test starts the scheduler.
       
   177   4) The timer event gets processed in CPowerdownClient::RunL() - it initiates a powerdown
       
   178      sequence.
       
   179   5) The shutdown server will notify the client (CPowerdownClient), calling 
       
   180      CPowerdownClient::SaveL() method.
       
   181   6) CPowerdownClient::SaveL() will call CSaveNotifier::DelayRequeue() not to re-register itself. 
       
   182      Then it will raise a timer event, which will be processed after 1 second.
       
   183   7) The second timer event gets processed in CPowerdownClient::RunL() - it calls 
       
   184      CSaveNotifier::HandleError(). 
       
   185      Without the fix CSaveNotifier::HandleError() causes "BadHandle" panic on the server side.
       
   186 
       
   187 @SYMTestCaseID          SYSLIB-PWRLCLI-CT-3686
       
   188 @SYMTestCaseDesc	    Tests for defect number DEF048920
       
   189 @SYMTestPriority 	    High
       
   190 @SYMTestActions  	    Initiate a powerdown sequence.The shutdown server will notify the client,which delays the 
       
   191                         power off and then raises a timer event which stops the scheduler   
       
   192 @SYMTestExpectedResults Test must not fail
       
   193 @SYMREQ                 REQ0000
       
   194 */		
       
   195 void DEF048920L()
       
   196     {	
       
   197 	CActiveScheduler* scheduler = new CActiveScheduler;
       
   198     __LEAVE_IF_NULL(scheduler);
       
   199     CleanupStack::PushL(scheduler);
       
   200 	CActiveScheduler::Install(scheduler);
       
   201 
       
   202     CPowerdownClient* powerdownClient = CPowerdownClient::NewLC();
       
   203 
       
   204 	CActiveScheduler::Start();
       
   205 
       
   206     CleanupStack::PopAndDestroy(powerdownClient);
       
   207     CleanupStack::PopAndDestroy(scheduler);
       
   208     }
       
   209 
       
   210 
       
   211 
       
   212 // This test class is used to receive a powerdown notification from the shutdown server.
       
   213 // Its SaveL() calls MSaveObserver::DelayRequeue() not to re-register itself. Its RunL() may call 
       
   214 // CSaveNotifier::HandleError() to send error to the server. But both behaviors will not stop the server's 
       
   215 // shutdown execution.
       
   216 class CPowerdownClient2 : public CActive, public MSaveObserver
       
   217     {
       
   218 public:
       
   219     static CPowerdownClient2* NewLC();
       
   220     virtual ~CPowerdownClient2();
       
   221     virtual void SaveL(MSaveObserver::TSaveType aSaveType);
       
   222 
       
   223 protected:
       
   224 	virtual void DoCancel();
       
   225 	virtual void RunL();
       
   226 
       
   227 private:
       
   228     CPowerdownClient2();
       
   229     void ConstructL();
       
   230 
       
   231 private:
       
   232 	enum TTestSteps
       
   233 		{
       
   234 		TRequestSwitchOff1,
       
   235 		TClientSave1,
       
   236 		TClientCheckServerPowerOff1,		
       
   237 		TRequestSwitchOff2,
       
   238 		TClientSave2,
       
   239 		TClientSendError,
       
   240 		TClientCheckServerPowerOff2,
       
   241 		TTestStepEnd,
       
   242 		};
       
   243 
       
   244 private:
       
   245     RTimer iTimer;
       
   246     CSaveNotifier* iSaveNotifier;
       
   247     TTestSteps iTestStep;
       
   248     };
       
   249 
       
   250 CPowerdownClient2* CPowerdownClient2::NewLC()
       
   251     {
       
   252     CPowerdownClient2* self = new CPowerdownClient2();
       
   253     __LEAVE_IF_NULL(self);
       
   254     CleanupStack::PushL(self);
       
   255     self->ConstructL();
       
   256     return self;
       
   257     }
       
   258 
       
   259 CPowerdownClient2::~CPowerdownClient2()
       
   260     {
       
   261     Cancel();
       
   262     iTimer.Close();
       
   263     delete iSaveNotifier;
       
   264     }
       
   265 
       
   266 //MSaveNotifier::SaveL() implementation. Called when powerdown event occurs.
       
   267 void CPowerdownClient2::SaveL(MSaveObserver::TSaveType)
       
   268     {
       
   269 	__ASSERT_ALWAYS(iTestStep == TClientSave1 || iTestStep == TClientSave2, \
       
   270 		TheTest.Panic(KErrNotSupported, KTestFailed, iTestStep));
       
   271 	
       
   272 	TBool powerOff = EFalse;
       
   273 	
       
   274 	// Checks the power state of the server. It should be off because the server has received
       
   275 	// the power off request.
       
   276 	// Calls DelayRequeue() not to re-register itself.
       
   277 	// Starts a timer which is longer than the server's shutdown timer.
       
   278 	// Move to next test step
       
   279 	if(iTestStep == TClientSave1)
       
   280 		{
       
   281 		iSaveNotifier->ServerPowerState(powerOff);
       
   282 		TEST(powerOff);		
       
   283 		iSaveNotifier->DelayRequeue();
       
   284    		iTestStep = TClientCheckServerPowerOff1;
       
   285    		iTimer.After(iStatus, KShtdwnTimeoutLonger);
       
   286    		TEST2(iStatus.Int(), KRequestPending);
       
   287    		SetActive();
       
   288 		}
       
   289 
       
   290 	// Checks the power state of the server. It should be off because the server has received
       
   291 	// the power off request.
       
   292 	// Calls DelayRequeue() not to re-register itself.
       
   293 	// Starts a timer which is shorter than the server's shutdown timer.
       
   294 	// Move to next test step
       
   295    	if(iTestStep == TClientSave2)
       
   296    		{
       
   297 		iSaveNotifier->ServerPowerState(powerOff);
       
   298 		TEST(powerOff);		
       
   299 		iSaveNotifier->DelayRequeue();
       
   300 		iTestStep = TClientSendError;
       
   301    		iTimer.After(iStatus, KShtdwnTimeoutShorter);
       
   302    		TEST2(iStatus.Int(), KRequestPending);
       
   303    		SetActive();
       
   304    		}
       
   305     }
       
   306 
       
   307 void CPowerdownClient2::DoCancel()
       
   308     {
       
   309     iTimer.Cancel();
       
   310     }
       
   311 
       
   312 //Processes timer events.
       
   313 void CPowerdownClient2::RunL()
       
   314     {
       
   315 	__ASSERT_ALWAYS(iTestStep == TRequestSwitchOff1 || iTestStep == TClientCheckServerPowerOff1 ||\
       
   316 				 iTestStep == TClientSendError, TheTest.Panic(KErrNotSupported, KTestFailed, iTestStep));    
       
   317 	
       
   318 	TBool powerOff = ETrue;
       
   319 	
       
   320 	// Requests server for switchoff for the first time
       
   321     if(iTestStep == TRequestSwitchOff1)
       
   322     	{
       
   323     	TEST2(iSaveNotifier->SwitchOff(MSaveObserver::ESaveAll, ETrue), KErrNone);
       
   324     	iTestStep = TClientSave1;
       
   325     	}
       
   326     
       
   327 	// Checks the power state of the server. It should be on because CServShutdownServer::SwitchOff()
       
   328 	// has been called.
       
   329     // Requests server for switchoff for the second time.
       
   330     if(iTestStep == TClientCheckServerPowerOff1)
       
   331     	{
       
   332 		iSaveNotifier->ServerPowerState(powerOff);
       
   333 		TEST(!powerOff);
       
   334     	iSaveNotifier->Queue(); // client re-register after the system resumes.
       
   335     	iTestStep = TRequestSwitchOff2;
       
   336     	User::After(KOneSec);
       
   337     	iTestStep = TClientSave2;
       
   338     	TEST2(iSaveNotifier->SwitchOff(MSaveObserver::ESaveAll, ETrue), KErrNone);
       
   339     	}
       
   340     	
       
   341 	// Checks the power state of the server. It should be off because CServShutdownServer::SwitchOff()
       
   342 	// has not been called.
       
   343 	// Sends error to server. The server will ignore the error message. 
       
   344 	// HandleError re-registers the client thus triggers the CServShutdownServer::SwitchOff().
       
   345 	// Checks the power state of the server again. It should be on because CServShutdownServer::SwitchOff()
       
   346 	// has been called.
       
   347 	// Stops the active scheduler.
       
   348     if(iTestStep == TClientSendError)
       
   349     	{
       
   350 		iSaveNotifier->ServerPowerState(powerOff);
       
   351 		TEST(powerOff);	
       
   352     	iSaveNotifier->HandleError(KErrGeneral);
       
   353     	iTestStep = TClientCheckServerPowerOff2;
       
   354     	User::After(KOneSec);
       
   355 		iSaveNotifier->ServerPowerState(powerOff);
       
   356 		TEST(!powerOff);		
       
   357 		iTestStep = TTestStepEnd;
       
   358 		CActiveScheduler::Stop();
       
   359     	}
       
   360     }
       
   361 
       
   362 //Adds the CPowerdownClient2 object to the active scheduler.
       
   363 CPowerdownClient2::CPowerdownClient2() :
       
   364     CActive(CActive::EPriorityStandard), iTestStep(TRequestSwitchOff1)
       
   365     {
       
   366 	CActiveScheduler::Add(this);
       
   367     }
       
   368 
       
   369 //Constructs CPowerdownClient2 object and generates a timer event, processed 1 second later.
       
   370 void CPowerdownClient2::ConstructL()
       
   371     {
       
   372     iSaveNotifier = CSaveNotifier::NewL(*this);
       
   373     __LEAVE_IF_ERROR(iTimer.CreateLocal());
       
   374     iTimer.After(iStatus, KOneSec);
       
   375     TEST2(iStatus.Int(), KRequestPending);
       
   376     SetActive();
       
   377     }
       
   378 
       
   379 
       
   380 /**
       
   381   DEF111025 - Device restarts from PREQ1089 UIF functionality can be delayed indefinitely.
       
   382   What this test does is:
       
   383   1) The test creates a CPowerdownClient2 object, which raises a 1-second timer event. The test starts 
       
   384      the scheduler.
       
   385   2) The timer event gets processed in CPowerdownClient2::RunL() - it initiates a powerdown
       
   386      sequence.
       
   387   3) The shutdown server notifies the client (CPowerdownClient2), calling CPowerdownClient2::SaveL() 
       
   388      method.
       
   389   4) CPowerdownClient2::SaveL() gets the power state of the server and checks whether it is off to ensure 
       
   390      the server has received the shutdown request but not executed CServShutdownServer::SwitchOff() yet. 
       
   391      It calls CSaveNotifier::DelayRequeue() not to re-register itself. 
       
   392      Then it raises a timer, which is longer than the shutdown timer defined at the server side.
       
   393   5) The timer event gets processed in CPowerdownClient::RunL(). It gets the power state of the server 
       
   394      and checks whether it is on to ensure the server has had CServShutdownServer::SwitchOff() executed by 
       
   395      the shutdown timer. 
       
   396      Then it initiates a powerdown sequence for the second time.
       
   397   6) The shutdown server notifies the client (CPowerdownClient2), calling  CPowerdownClient2::SaveL() 
       
   398      method.
       
   399   7) CPowerdownClient2::SaveL() gets the power state of the server and checks whether it is off to ensure 
       
   400      the server has received the shutdown request but not executed CServShutdownServer::SwitchOff() yet. 
       
   401      It calls CSaveNotifier::DelayRequeue() not to re-register itself. 
       
   402      Then it raises a timer, which is shorter than the shutdown timer defined at the server side.
       
   403   8) The timer event gets processed in CPowerdownClient::RunL(). It gets the power state of the server 
       
   404      and checks whether it is off to ensure the server still has not executed CServShutdownServer::SwitchOff(). 
       
   405      It calls CSaveNotifier::HandleError() to send an error to the server. After sometime, It gets the power 
       
   406      state of the server again and checks whether it is on to ensure the server has had 
       
   407      CServShutdownServer::SwitchOff() executed by the shutdown timer.
       
   408      Then it stops the active scheduler.
       
   409      
       
   410   Without the fix the checking of power state of the server would fail in a certain step.
       
   411 
       
   412 @SYMTestCaseID          SYSLIB-PWRCLI-CT-4001
       
   413 @SYMTestCaseDesc	    Tests for defect number DEF111025
       
   414 @SYMTestPriority 	    High
       
   415 @SYMTestActions  	    Initiates a powerdown sequence which sends 2 poweroff requests to server. The shutdown 
       
   416 					    server will notify the client twice. The first time when being notified, the client will 
       
   417 					    not re-register itself. For the second time, it will send error to the server. During 
       
   418 					    this procedure, some checkpoints will be set to check the power states of the server.
       
   419 @SYMTestExpectedResults The test program should not panic or leave. At power state checkpoints, the power states 
       
   420 						queried from the server should be the expected values.
       
   421 @SYMDEF                 DEF111025
       
   422 */		
       
   423 void DEF111025L()
       
   424 	{	
       
   425 	CActiveScheduler* scheduler = new CActiveScheduler;
       
   426     __LEAVE_IF_NULL(scheduler);
       
   427     CleanupStack::PushL(scheduler);
       
   428 	CActiveScheduler::Install(scheduler);
       
   429 	
       
   430     CPowerdownClient2* powerdownClientTimer = CPowerdownClient2::NewLC();
       
   431 
       
   432 	CActiveScheduler::Start();
       
   433 	CleanupStack::PopAndDestroy(powerdownClientTimer);
       
   434     CleanupStack::PopAndDestroy(scheduler);
       
   435 	}
       
   436 //
       
   437 //
       
   438 //Tests
       
   439 
       
   440 static void DoRunL()
       
   441     {
       
   442 	TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-PWRLCLI-CT-3686  DEF048920 "));
       
   443     ::DEF048920L(); 
       
   444     TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-PWRCLI-CT-4001 DEF111025 "));
       
   445     ::DEF111025L();
       
   446     }
       
   447 
       
   448 TInt E32Main()
       
   449 	{
       
   450 	__UHEAP_MARK;
       
   451 	CTrapCleanup* tc = CTrapCleanup::New();
       
   452     TEST(tc != NULL);
       
   453 
       
   454 	TheTest.Start(_L("Power shutdown tests"));
       
   455 
       
   456     TRAPD(err, ::DoRunL());
       
   457 	TEST2(err, KErrNone);
       
   458 
       
   459 	TheTest.End();
       
   460 	TheTest.Close();
       
   461 	
       
   462 	delete tc;
       
   463 
       
   464 	__UHEAP_MARKEND;
       
   465 
       
   466 	User::Heap().Check();
       
   467 	return KErrNone;
       
   468 	}