Update contrib.
1 // Copyright (c) 1996-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 the License "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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\system\t_chnot.cpp
15 // Tests RChangeNotifier class
17 // Tests RChangeNotifier class
21 // - Create a RChangeNotifier object and verify the logon status is
23 // - Call the Logon and LogonCancel methods, verify results are as
25 // - Test for the correct midnight crossover notifier results in a
26 // variety of situations: DST On, DST Off, various time offsets
28 // - Test various locale changes and verify that the notifier response
30 // - Test the notification of the death of a thread and check that
31 // results are as expected. Check for normal exit, kill exit,
32 // terminate exit and panic exit.
33 // Platforms/Drives/Compatibility:
35 // Assumptions/Requirement/Pre-requisites:
36 // Failures and causes:
37 // Base Port information:
41 #define __E32TEST_EXTENSION__
47 #include <e32def_private.h>
49 RTest test(_L("T_CHNOT"));
51 RChangeNotifier notifier;
53 void TestStat(const TRequestStatus& aStat, TInt aValue)
55 if (aStat.Int()!=aValue)
57 test.Printf(_L("Got %08x Expected %08x\n"),aStat.Int(),aValue);
68 // Expect all except EChangesLowMemory
71 EChangesMidnightCrossover |
82 void TestLogonLogoff()
85 notifier.LogonCancel();
87 TestStat(stat,KRequestPending);
88 notifier.LogonCancel();
89 TestStat(stat,KErrCancel);
90 notifier.LogonCancel();
91 TestStat(stat,KErrCancel);
98 TDateTime dateTime=time.DateTime();
100 dateTime.SetMinute(59);
101 dateTime.SetSecond(58);
102 dateTime.SetMicroSecond(700000);
105 TInt r=notifier.Logon(stat);
107 TestStat(stat,KRequestPending);
108 test(User::SetHomeTime(time)==KErrNone);
110 TDateTime dateTime2=time.DateTime();
111 User::WaitForRequest(stat);
112 TestStat(stat,EChangesSystemTime);
113 r=notifier.Logon(stat);
115 User::WaitForRequest(stat);
117 TestStat(stat,EChangesMidnightCrossover);
118 dateTime2=time.DateTime();
119 test(dateTime2.Second()==0);
120 test(dateTime2.Minute()==0);
121 test(dateTime2.Hour()==0);
122 if (dateTime2.Month()==dateTime.Month())
123 test(dateTime2.Day()==dateTime.Day()+1);
125 test(dateTime2.Day()==0);
127 r=notifier.Logon(stat);
129 TestStat(stat,KRequestPending);
130 test(User::SetHomeTime(time)==KErrNone);
131 User::WaitForRequest(stat);
132 TestStat(stat,(EChangesSystemTime|EChangesMidnightCrossover));
134 r=notifier.Logon(stat);
136 TestStat(stat,KRequestPending);
137 test(User::SetHomeTime(time)==KErrNone);
138 User::WaitForRequest(stat);
139 TestStat(stat,(EChangesSystemTime|EChangesMidnightCrossover));
141 // Check that a change of secure time also triggers notification, even though the user time is unchanged
142 r = notifier.Logon(stat);
144 TestStat(stat, KRequestPending);
145 if ((r = time.HomeTimeSecure()) == KErrNone)
146 r = User::SetHomeTimeSecure(time+TTimeIntervalSeconds(60));
149 test(User::SetHomeTimeSecure(time) == KErrNone);
150 r = EChangesSystemTime;
154 RDebug::Printf("WARNING: Secure clock change test skipped because secure time could not be changed!");
155 notifier.LogonCancel();
158 User::WaitForRequest(stat);
162 void SetOffsetForMidnight(TTime time,TTimeIntervalSeconds offset)
164 test(User::SetHomeTime(time)==KErrNone);
165 User::SetUTCOffset(offset);
166 // No longer need next line, as we now only get one notification
167 // User::After(999999);//So, if time has gone backwards, midnight crossover has been noticed
169 notifier.Logon(stat);
170 User::WaitForRequest(stat);
171 test(stat.Int()&(EChangesSystemTime|EChangesLocale));
174 void TestMidnightCrossover()
176 TTimeIntervalSeconds offset=User::UTCOffset();
179 test.Start(_L("Normal"));
181 test.Next(_L("Now offset 0"));
182 SetOffsetForMidnight(time,0);
184 test.Next(_L("Now offset +30"));
185 SetOffsetForMidnight(time,30);
187 test.Next(_L("Now offset -30"));
188 SetOffsetForMidnight(time,-30);
190 test.Next(_L("Now offset +60"));
191 SetOffsetForMidnight(time,60);
193 test.Next(_L("Now offset -60"));
194 SetOffsetForMidnight(time,-60);
196 test.Next(_L("Now offset +120"));
197 SetOffsetForMidnight(time,120);
199 test.Next(_L("Now offset -120"));
200 SetOffsetForMidnight(time,-120);
203 TTime time1998=TDateTime(1998,EFebruary,2,3,4,5,6);
204 test.Next(_L("1998 offset 0"));
205 SetOffsetForMidnight(time1998,0);
207 test.Next(_L("1998 offset +30"));
208 SetOffsetForMidnight(time1998,30);
210 test.Next(_L("1998 offset -30"));
211 SetOffsetForMidnight(time1998,-30);
213 test.Next(_L("1998 offset +60"));
214 SetOffsetForMidnight(time1998,60);
216 test.Next(_L("1998 offset -60"));
217 SetOffsetForMidnight(time1998,-60);
219 test.Next(_L("1998 offset +120"));
220 SetOffsetForMidnight(time1998,120);
222 test.Next(_L("1998 offset -120"));
223 SetOffsetForMidnight(time1998,-120);
226 TTime time1999=TDateTime(1999,EDecember,30,3,4,5,6);
227 test.Next(_L("1999 offset 0"));
228 SetOffsetForMidnight(time1999,0);
232 test(now.DateTime().Year()==2000);
233 test(now.DateTime().Month()==EJanuary);
234 test.Next(_L("1999 offset +30"));
235 SetOffsetForMidnight(time1999,30);
238 test(now.DateTime().Year()==2000);
239 test(now.DateTime().Month()==EJanuary);
240 test.Next(_L("1999 offset -30"));
241 SetOffsetForMidnight(time1999,-30);
244 test(now.DateTime().Year()==2000);
245 test(now.DateTime().Month()==EJanuary);
246 test.Next(_L("1999 offset +60"));
247 SetOffsetForMidnight(time1999,60);
250 test(now.DateTime().Year()==2000);
251 test(now.DateTime().Month()==EJanuary);
252 test.Next(_L("1999 offset -60"));
253 SetOffsetForMidnight(time1999,-60);
256 test(now.DateTime().Year()==2000);
257 test(now.DateTime().Month()==EJanuary);
258 test.Next(_L("1999 offset +120"));
259 SetOffsetForMidnight(time1999,120);
262 test(now.DateTime().Year()==2000);
263 test(now.DateTime().Month()==EJanuary);
264 test.Next(_L("1999 offset -120"));
265 SetOffsetForMidnight(time1999,-120);
268 test(now.DateTime().Year()==2000);
269 test(now.DateTime().Month()==EJanuary);
271 TTime time2002=TDateTime(2002,EAugust,30,3,4,5,6);
272 test.Next(_L("2002 offset 0"));
273 SetOffsetForMidnight(time2002,0);
275 test.Next(_L("2002 offset +30"));
276 SetOffsetForMidnight(time2002,30);
278 test.Next(_L("2002 offset -30"));
279 SetOffsetForMidnight(time2002,-30);
281 test.Next(_L("2002 offset +60"));
282 SetOffsetForMidnight(time2002,60);
284 test.Next(_L("2002 offset -60"));
285 SetOffsetForMidnight(time2002,-60);
287 test.Next(_L("2002 offset +120"));
288 SetOffsetForMidnight(time2002,120);
290 test.Next(_L("2002 offset -120"));
291 SetOffsetForMidnight(time2002,-120);
294 SetOffsetForMidnight(time,offset);
298 void TestLocaleChanges()
301 notifier.Logon(stat);
302 TestStat(stat,KRequestPending);
305 User::WaitForRequest(stat);
306 TestStat(stat,EChangesLocale);
309 void TestOffsetChanges()
311 TTimeIntervalSeconds oldOffset = User::UTCOffset();
312 User::SetUTCOffset(0);
317 TDateTime dateTime=time.DateTime();
318 dateTime.SetHour(23);
319 dateTime.SetMinute(30);
320 dateTime.SetSecond(0);
321 dateTime.SetMicroSecond(0);
323 test(User::SetHomeTime(time)==KErrNone);
324 notifier.Logon(stat);
325 User::WaitForRequest(stat);
326 TestStat(stat,(EChangesSystemTime));
328 notifier.Logon(stat);
329 TestStat(stat,KRequestPending);
330 User::SetUTCOffset(3600);
331 User::WaitForRequest(stat);
332 TestStat(stat,(EChangesSystemTime|EChangesLocale|EChangesMidnightCrossover));
333 User::SetUTCOffset(oldOffset);
334 notifier.Logon(stat);
335 User::WaitForRequest(stat);
338 const TInt retValue=65432;
339 const TInt killValue=2081953;
340 const TInt terminateValue=512123;
341 const TInt panicValue=1257671;
342 const TInt KHeapSize=0x200;
344 TInt ThreadCode(TAny* aReturnImmetiateFlag)
346 if(!aReturnImmetiateFlag)
347 User::After(60000000); // wait a minute, (effectively forever as far as the test goes).
351 void TestThreadDeath()
353 test.Start(_L("Normal Exit"));
355 TInt r=thread.Create(_L("T_CHNOT ThreadCode"),ThreadCode,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ETrue);
358 TRequestStatus threadStat;
359 thread.Logon(threadStat);
361 notifier.Logon(stat);
362 TestStat(stat,KRequestPending);
364 User::WaitForRequest(stat);
365 TestStat(stat,EChangesThreadDeath);
366 test(threadStat==retValue);
367 test(thread.ExitReason()==retValue);
368 test(thread.ExitType()==EExitKill);
369 test(thread.ExitCategory()==_L("Kill"));
370 CLOSE_AND_WAIT(thread);
373 test.Next(_L("Kill"));
374 r=thread.Create(_L("T_CHNOT ThreadCode"),ThreadCode,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
376 thread.Logon(threadStat);
377 notifier.Logon(stat);
378 TestStat(stat,KRequestPending);
380 thread.Kill(killValue);
381 User::WaitForRequest(stat);
382 TestStat(stat,EChangesThreadDeath);
383 test(threadStat==killValue);
384 test(thread.ExitReason()==killValue);
385 test(thread.ExitType()==EExitKill);
386 test(thread.ExitCategory()==_L("Kill"));
387 CLOSE_AND_WAIT(thread);
389 test.Next(_L("Terminate"));
390 r=thread.Create(_L("T_CHNOT ThreadCode"),ThreadCode,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
392 thread.Logon(threadStat);
393 notifier.Logon(stat);
394 TestStat(stat,KRequestPending);
396 thread.Terminate(terminateValue);
397 User::WaitForRequest(stat);
398 TestStat(stat,EChangesThreadDeath);
399 test(threadStat==terminateValue);
400 test(thread.ExitReason()==terminateValue);
401 test(thread.ExitType()==EExitTerminate);
402 test(thread.ExitCategory()==_L("Terminate"));
403 CLOSE_AND_WAIT(thread);
405 test.Next(_L("Panic"));
406 r=thread.Create(_L("T_CHNOT ThreadCode"),ThreadCode,KDefaultStackSize,KHeapSize,KHeapSize,NULL);
408 thread.Logon(threadStat);
409 notifier.Logon(stat);
410 TestStat(stat,KRequestPending);
411 TBool justInTime=User::JustInTime();
412 User::SetJustInTime(EFalse);
414 thread.Panic(_L("Testing panic"),panicValue);
415 User::WaitForRequest(stat);
416 User::SetJustInTime(justInTime);
417 TestStat(stat,EChangesThreadDeath);
418 test(threadStat==panicValue);
419 test(thread.ExitReason()==panicValue);
420 test(thread.ExitType()==EExitPanic);
421 test(thread.ExitCategory()==_L("Testing panic"));
422 CLOSE_AND_WAIT(thread);
426 void TestCloseWhilstPending()
428 test_KErrNone(notifier.Create());
430 test_KErrNone(notifier.Logon(stat));
431 User::WaitForRequest(stat);
432 test_KErrNone(notifier.Logon(stat));
434 test_Equal(KErrGeneral,stat.Int());
437 void TestCloseAndCompleteRace()
439 RThread().SetPriority(EPriorityRealTime);
442 RChangeNotifier notifier2;
443 test_KErrNone(notifier2.Create());
444 TRequestStatus stat2;
445 test_KErrNone(notifier2.Logon(stat2));
446 User::WaitForRequest(stat2);
447 test_KErrNone(notifier2.Logon(stat2));
450 test_KErrNone(notifier.Create());
452 test_KErrNone(notifier.Logon(stat));
453 User::WaitForRequest(stat);
454 test_KErrNone(notifier.Logon(stat));
456 // create and kill a thread so notifiers get signaled
458 test_KErrNone(thread.Create(_L("T_CHNOT ThreadCode"),ThreadCode,KDefaultStackSize,KHeapSize,KHeapSize,NULL));
461 // wait for notifier2
462 User::WaitForRequest(stat2);
464 // as this thread is realtime priority, then (on unicore systems) it has preempted
465 // kernel supervisor thread after it completed 'notifier2' but before it completed
466 // 'notifier'. if we close both notifiers now we trigger a race conidition which
467 // previousely caused a null pointer dereference in the kernel...
471 User::WaitForRequest(stat);
472 TInt result = stat.Int();
474 // expect KErrGeneral from closing notifier, or on SMP probably EChangesThreadDeath as
475 // the notifier had time to complete
476 const TInt numCpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
477 if(numCpus==1 || result!=EChangesThreadDeath)
478 test_Equal(KErrGeneral,result);
480 RThread().SetPriority(EPriorityNormal);
487 User::After(1000000);//So WINS doesn't give an instant power-status change;
488 test.Start(_L("Create"));
491 test.Next(_L("Close"));
494 test.Next(_L("Create"));
497 test.Next(_L("Logon/Logoff"));
500 test.Next(_L("Midnight crossover"));
501 TestMidnightCrossover();
503 test.Next(_L("Locale changes"));
506 test.Next(_L("Offset changes"));
509 test.Next(_L("Thread death"));
512 test.Next(_L("Close"));
515 test.Next(_L("Close whilst pending"));
516 TestCloseWhilstPending();
518 test.Next(_L("Race between Close and complete"));
519 TestCloseAndCompleteRace();