|
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 } |