Update contrib.
1 // Copyright (c) 1995-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\active\t_cactw.cpp
16 // Test the CActiveSchedulerWait class.
18 // CActiveSchedulerWait
20 // - Verify the thread is panicked when one of the following programming errors occurs:
21 // - the scheduler is started twice.
22 // - the scheduler is stopped without starting scheduler.
23 // - the scheduler is started and then stopped twice.
24 // - the CanStopNow method of scheduler is called without starting scheduler.
25 // - Run different combinations of wait, start, async stop, async stop with a callback,
26 // canstopnow and nested calls to start and async stop operations and verify they run
28 // - Check the heap is not corrupted by all the tests.
29 // Platforms/Drives/Compatibility:
31 // Assumptions/Requirement/Pre-requisites:
32 // Failures and causes:
33 // Base Port information:
40 const TInt KPanicThreadRet = 222;
41 const TInt KHeapSize = 0x1000;
42 const TInt KMaxActions = 32;
43 const TInt KNumWaits = 2;
45 enum TDirective {ENormal,EStartTwice,EStopUnstarted,EStopTwice,ECanStopNotStarted};
46 enum TActionType {EStartWait, EStopWait, EStopWaitCallBack, EIsWaitStarted, ECanStopWait, EStart, EStop};
54 class TSchedulerTester
60 void SubTest2(TAction* aActions, TInt aCount, const TDesC& aResult);
63 class CActionRunner : public CActive
68 void SetActions(TAction* aActions, TInt aCount);
70 const TDesC& Trace() const;
74 static TInt CallBack(TAny* aThis);
78 TAction iActions[KMaxActions];
79 CActiveSchedulerWait iWait[KNumWaits];
84 LOCAL_D RTest test(_L("T_CACTW"));
85 LOCAL_D RSemaphore threadSemaphore;
88 CActionRunner::CActionRunner() : CActive(EPriorityStandard)
90 CActiveScheduler::Add(this);
93 CActionRunner::~CActionRunner()
98 void CActionRunner::SetActions(TAction* aActions, TInt aCount)
100 iNumActions = aCount;
101 for (TInt ii=0; ii<aCount && ii<KMaxActions; ii++)
102 iActions[ii] = aActions[ii];
105 void CActionRunner::Start()
107 TRequestStatus* s = &iStatus;
109 User::RequestComplete(s, KErrNone);
112 void CActionRunner::DoCancel()
116 void CActionRunner::RunL()
119 if (iStep < iNumActions)
121 TAction& action = iActions[iStep];
122 CActiveSchedulerWait& wait = iWait[action.iId];
123 iTrace.AppendFormat(_L("%d%dS"), action.iId, action.iType);
125 switch (action.iType)
133 case EStopWaitCallBack:
134 wait.AsyncStop(TCallBack(CallBack, this));
137 iTrace.AppendFormat(_L("%d"), wait.IsStarted()!=0);
140 iTrace.AppendFormat(_L("%d"), wait.CanStopNow()!=0);
143 CActiveScheduler::Start();
146 CActiveScheduler::Stop();
151 iTrace.AppendFormat(_L("%d%dE"), action.iId, action.iType);
155 const TDesC& CActionRunner::Trace() const
160 TInt CActionRunner::CallBack(TAny* aThis)
162 CActionRunner* self = (CActionRunner*) aThis;
163 self->iTrace.Append(_L("C"));
168 LOCAL_D TInt panicThread(TAny* aDirective)
170 // Test thread which panics
173 // cause panics in various ways depending upon aDirective
174 CActiveScheduler* pManager=new CActiveScheduler;
175 CActiveScheduler::Install(pManager);
177 CActionRunner* r = new(ELeave)CActionRunner;
179 switch((TInt)aDirective)
183 TAction actions[] = {{EStop, 0}};
184 r->SetActions(actions, sizeof(actions)/sizeof(*actions));
189 TAction actions[] = {{EStartWait, 0}, {EStartWait, 0}, {EStop, 0}};
190 r->SetActions(actions, sizeof(actions)/sizeof(*actions));
195 TAction actions[] = {{EStopWait, 0}, {EStop, 0}};
196 r->SetActions(actions, sizeof(actions)/sizeof(*actions));
201 TAction actions[] = {{EStartWait, 0}, {EStopWait, 0}, {EStopWait, 0}, {EStop, 0}};
202 r->SetActions(actions, sizeof(actions)/sizeof(*actions));
205 case ECanStopNotStarted:
207 TAction actions[] = {{ECanStopWait, 0}, {EStop, 0}};
208 r->SetActions(actions, sizeof(actions)/sizeof(*actions));
216 CActiveScheduler::Start();
219 return(KPanicThreadRet);
223 void TSchedulerTester::Test1()
236 test.Start(_L("First test normal thread termination"));
237 TInt r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ENormal);
241 User::WaitForRequest(stat);
242 test(thread.ExitCategory().Compare(_L("Kill"))==0);
243 test(thread.ExitReason()==KPanicThreadRet);
244 test(thread.ExitType()==EExitKill);
245 CLOSE_AND_WAIT(thread);
247 test.Next(_L("Two starts panics"));
248 r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStartTwice);
252 User::WaitForRequest(stat);
253 test(thread.ExitReason()==EActiveSchedulerWaitAlreadyStarted);
254 test(thread.ExitType()==EExitPanic);
255 CLOSE_AND_WAIT(thread);
257 test.Next(_L("Stop without start panics"));
258 r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopUnstarted);
262 User::WaitForRequest(stat);
263 test(thread.ExitReason()==EActiveSchedulerWaitNotStarted);
264 test(thread.ExitType()==EExitPanic);
265 CLOSE_AND_WAIT(thread);
267 test.Next(_L("Start then two stops panics"));
268 r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopTwice);
272 User::WaitForRequest(stat);
273 test(thread.ExitReason()==EActiveSchedulerWaitNotStarted);
274 test(thread.ExitType()==EExitPanic);
275 CLOSE_AND_WAIT(thread);
277 test.Next(_L("Can stop now, without start panics"));
278 r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ECanStopNotStarted);
282 User::WaitForRequest(stat);
283 test(thread.ExitReason()==EActiveSchedulerWaitNotStarted);
284 test(thread.ExitType()==EExitPanic);
285 CLOSE_AND_WAIT(thread);
290 void TSchedulerTester::Test2()
297 test.Start(_L("Scheduler wait sequencing"));
299 test.Next(_L("First a simple stop"));
300 TAction a[] = {{EStop, 0}};
301 SubTest2(a, sizeof(a)/sizeof(*a), _L("06S06E"));
304 test.Next(_L("Simple wait stop"));
305 TAction a[] = { {EIsWaitStarted, 0}, {EStartWait, 0}, {EIsWaitStarted, 0},
306 {ECanStopWait, 0}, {EStopWait, 0}, {EIsWaitStarted, 0},
308 SubTest2(a, sizeof(a)/sizeof(*a), _L("03S003E00S03S103E04S104E01S01E00E03S003E06S06E"));
311 test.Next(_L("Properly nested wait"));
312 TAction a[] = { {EStartWait, 0}, {EStartWait, 1},
313 {EStopWait, 1}, {EStopWait, 0}, {EStop, 0}};
314 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S11S11E10E01S01E00E06S06E"));
317 test.Next(_L("Properly nested scheduler"));
318 TAction a[] = { {EStart, 0}, {EStart, 1},
319 {EStop, 1}, {EStop, 0}, {EStop, 0}};
320 SubTest2(a, sizeof(a)/sizeof(*a), _L("05S15S16S16E15E06S06E05E06S06E"));
323 test.Next(_L("Badly nested wait"));
324 TAction a[] = { {EStartWait, 0}, {EStartWait, 1},
325 {EStopWait, 0}, {EStopWait, 1}, {EStop, 0}};
326 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S01S01E11S11E10E00E06S06E"));
329 test.Next(_L("Badly nested scheduler"));
330 TAction a[] = { {EStart, 0}, {EStart, 1},
331 {EStop, 0}, {EStop, 1}, {EStop, 0}};
332 SubTest2(a, sizeof(a)/sizeof(*a), _L("05S15S06S06E15E16S16E05E06S06E"));
335 test.Next(_L("Bad mixed nesting 1"));
336 TAction a[] = { {EStartWait, 0}, {EStart, 1},
337 {EStopWait, 0}, {EStop, 1}, {EStop, 0}};
338 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S15S01S01E16S16E15E00E06S06E"));
341 test.Next(_L("Bad mixed nesting 2"));
342 TAction a[] = { {EStart, 0}, {EStartWait, 1},
343 {EStop, 0}, {EStopWait, 1}, {EStop, 0}};
344 SubTest2(a, sizeof(a)/sizeof(*a), _L("05S10S06S06E11S11E10E05E06S06E"));
347 test.Next(_L("Properly nested wait callback 1"));
348 TAction a[] = { {EStartWait, 0}, {EStartWait, 1},
349 {EStopWaitCallBack, 1}, {EStopWait, 0}, {EStop, 0}};
350 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S12S12EC10E01S01E00E06S06E"));
353 test.Next(_L("Properly nested wait callback 2"));
354 TAction a[] = { {EStartWait, 0}, {EStartWait, 1},
355 {EStopWait, 1}, {EStopWaitCallBack, 0}, {EStop, 0}};
356 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S11S11E10E02S02EC00E06S06E"));
359 test.Next(_L("Badly nested wait callback 1"));
360 TAction a[] = { {EStartWait, 0}, {EStartWait, 1},
361 {EStopWaitCallBack, 0}, {EStopWait, 1}, {EStop, 0}};
362 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S02S02E11S11E10EC00E06S06E"));
365 test.Next(_L("Badly nested wait callback 2"));
366 TAction a[] = { {EStartWait, 0}, {EStartWait, 1},
367 {EStopWait, 0}, {EStopWaitCallBack, 1}, {EStop, 0}};
368 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S01S01E12S12EC10E00E06S06E"));
371 test.Next(_L("Properly nested wait can stop now"));
372 TAction a[] = { {EStartWait, 0}, {EStartWait, 1}, {ECanStopWait, 0}, {ECanStopWait, 1},
373 {EStopWait, 1}, {ECanStopWait, 0}, {EStopWait, 0}, {EStop, 0}};
374 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S04S004E14S114E11S11E10E04S104E01S01E00E06S06E"));
377 test.Next(_L("Badly nested wait can stop now"));
378 TAction a[] = { {EStartWait, 0}, {EStartWait, 1}, {ECanStopWait, 0}, {ECanStopWait, 1},
379 {EStopWait, 0}, {ECanStopWait, 1}, {EStopWait, 1}, {EStop, 0}};
380 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S04S004E14S114E01S01E14S114E11S11E10E00E06S06E"));
383 test.Next(_L("Properly nested wait is started"));
384 TAction a[] = { {EStartWait, 0}, {EStartWait, 1}, {EIsWaitStarted, 0}, {EIsWaitStarted, 1},
385 {EStopWait, 1}, {EIsWaitStarted, 0}, {EIsWaitStarted, 1}, {EStopWait, 0}, {EStop, 0}};
386 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S03S103E13S113E11S11E10E03S103E13S013E01S01E00E06S06E"));
389 test.Next(_L("Badly nested wait is started"));
390 TAction a[] = { {EStartWait, 0}, {EStartWait, 1}, {EIsWaitStarted, 0}, {EIsWaitStarted, 1},
391 {EStopWait, 0}, {EIsWaitStarted, 0}, {EIsWaitStarted, 1}, {EStopWait, 1}, {EStop, 0}};
392 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S03S103E13S113E01S01E03S003E13S113E11S11E10E00E06S06E"));
395 test.Next(_L("Interleaved badly nested wait with callback"));
396 TAction a[] = { {EStartWait, 0}, {EStartWait, 1}, {EStopWaitCallBack, 0},
397 {EStartWait, 0}, {EStopWaitCallBack, 1}, {EStopWaitCallBack, 0},
399 SubTest2(a, sizeof(a)/sizeof(*a), _L("00S10S02S02E00S12S12E02S02EC00EC10EC00E06S06E"));
404 void TSchedulerTester::SubTest2(TAction* aActions, TInt aCount, const TDesC& aResult)
406 CActiveScheduler* pManager=new CActiveScheduler;
407 CActiveScheduler::Install(pManager);
409 CActionRunner* r = new(ELeave)CActionRunner;
410 r->SetActions(aActions, aCount);
412 CActiveScheduler::Start();
413 test(r->Trace() == aResult);
419 GLDEF_C TInt E32Main()
422 // don't want just in time debugging as we trap panics
423 TBool justInTime=User::JustInTime();
424 User::SetJustInTime(EFalse);
429 test.Start(_L("Test1"));
430 TSchedulerTester sched;
433 test.Next(_L("Test2"));
439 User::SetJustInTime(justInTime);