1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/active/t_cact.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,865 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\active\t_cact.cpp
1.18 +// Overview:
1.19 +// Test the CActiveScheduler class, including scheduling priority, thread
1.20 +// panics and cancelling objects attached to the scheduler.
1.21 +// API Information:
1.22 +// CActiveScheduler
1.23 +// Details:
1.24 +// - Verify the thread is panicked when one of the following programming errors occurs:
1.25 +// - start an uninstalled scheduler
1.26 +// - install a scheduler twice
1.27 +// - stop the scheduler twice
1.28 +// - stop an uninstalled scheduler
1.29 +// - set active an active object twice
1.30 +// - add an active object to an uninstalled scheduler
1.31 +// - add a NULL pointer to the scheduler
1.32 +// - add an active object twice
1.33 +// - thread gets a stray signal
1.34 +// - make request on an un-added active object
1.35 +// - Create timers with different priorities
1.36 +// - Check the timers are scheduled according to expiration time
1.37 +// - Check the timers are scheduled in order of their priority when they expire at the
1.38 +// same time
1.39 +// - Check the timers are scheduled in order of the addition to the scheduler when
1.40 +// they expire at the same time and they have the same priority
1.41 +// - Verify that a leave in RunL method not handled by the active object calls the active
1.42 +// scheduler's Error method
1.43 +// - Test a cancelled timer will not be scheduled
1.44 +// - Create a thread with its own heap and test that timers are scheduled in the order of
1.45 +// their expiration time, priority and order of addition to the scheduler
1.46 +// - Check the heap is not corrupted by all the tests
1.47 +// Platforms/Drives/Compatibility:
1.48 +// All
1.49 +// Assumptions/Requirement/Pre-requisites:
1.50 +// Failures and causes:
1.51 +// Base Port information:
1.52 +//
1.53 +//
1.54 +
1.55 +#include <e32test.h>
1.56 +#include <e32panic.h>
1.57 +
1.58 +const TInt KmyErrorNum=999;
1.59 +const TInt KLeaveCode=1234;
1.60 +const TInt KgTimerID=4321;
1.61 +const TInt KCancelCode=1111;
1.62 +const TInt KTestArraySize=10;
1.63 +const TInt KPanicThreadRet=2222;
1.64 +const TInt KHeapSize=0x2000;
1.65 +
1.66 +enum TActivePriority {eLowest=-100,eLow=-1,eNone=0,eHigh=1,eHighest=100};
1.67 +enum TDirective {EStartUninstalled,EInstallTwice,EStopTwice,EStopUninstalled,ESetActiveTwice,
1.68 + EAddToUninstalled,EAddNull,EAddTwice,ECreateStray,ERequestUnadded,EStraySignalNoKRequestPending,EStraySignalNoSetActive,ENormal};
1.69 +
1.70 +class TSecdulerTester
1.71 + {
1.72 +public:
1.73 + void Test1();
1.74 + void Test2();
1.75 + void Test3();
1.76 + void Test4();
1.77 + };
1.78 +
1.79 +class MyManager : public CActiveScheduler
1.80 + {
1.81 +public:
1.82 + virtual void Error(TInt anError) const {CActiveScheduler::Halt(anError);}
1.83 + };
1.84 +
1.85 +class myTimer : public CTimer
1.86 + {
1.87 +public:
1.88 + myTimer(const TInt aPriority, const TInt anIdentifier):CTimer(aPriority){iIdentifier=anIdentifier;}
1.89 + virtual void RunL();
1.90 + void Start();
1.91 + void Setactive() {SetActive();}
1.92 + static void SetNum(const TInt aNum) {iNum=aNum; iCount=0;}
1.93 +private:
1.94 + TInt iIdentifier;
1.95 + static TInt iCount;
1.96 + static TInt iNum;
1.97 + };
1.98 +
1.99 +class myThreadTimer : public CTimer
1.100 + {
1.101 +public:
1.102 + myThreadTimer(const TInt aPriority, const TInt anIdentifier):CTimer(aPriority){iIdentifier=anIdentifier;}
1.103 + virtual void RunL();
1.104 + static void SetNum(const TInt aNum) {iNum=aNum; iCount=0;}
1.105 + void Start();
1.106 +private:
1.107 + TInt iIdentifier;
1.108 + static TInt iCount;
1.109 + static TInt iNum;
1.110 + };
1.111 +
1.112 +class CreateStray : public CActive
1.113 + {
1.114 +public:
1.115 + CreateStray(TInt aPriority);
1.116 + void DoCancel() {}
1.117 + void RunL() {}
1.118 +private:
1.119 + RTimer iTimer;
1.120 + };
1.121 +
1.122 +class myStray : public CActive
1.123 + {
1.124 +public:
1.125 + myStray(TInt aPriority) : CActive(aPriority) {};
1.126 + void DoCancel() {}
1.127 + void RunL() { CActiveScheduler::Stop(); }
1.128 + void Start1();
1.129 + void Start2();
1.130 + };
1.131 +
1.132 +void myStray::Start1()
1.133 + {
1.134 + TRequestStatus* s=&iStatus;
1.135 + SetActive();
1.136 + RThread().RequestComplete(s,KErrNone);
1.137 + }
1.138 +
1.139 +void myStray::Start2()
1.140 + {
1.141 + TRequestStatus* s=&iStatus;
1.142 + iStatus=KRequestPending;
1.143 + User::RequestComplete(s,KErrNone);
1.144 + }
1.145 +
1.146 +TInt myTimer::iCount;
1.147 +TInt myTimer::iNum;
1.148 +TInt myThreadTimer::iCount;
1.149 +TInt myThreadTimer::iNum;
1.150 +
1.151 +LOCAL_D RTest test(_L("T_CACT"));
1.152 +LOCAL_D myTimer* gTimer; // This is cancelled from within the run method
1.153 +LOCAL_D RSemaphore threadSemaphore;
1.154 +LOCAL_D myTimer* pLowest=NULL;
1.155 +LOCAL_D myTimer* pLow=NULL;
1.156 +LOCAL_D myTimer* pNone=NULL;
1.157 +LOCAL_D myTimer* pHigh=NULL;
1.158 +LOCAL_D myTimer* pHigh2=NULL;
1.159 +LOCAL_D myTimer* pHigh3=NULL;
1.160 +LOCAL_D myTimer* pHighest=NULL;
1.161 +LOCAL_D TInt order[KTestArraySize]; // When a timer expires its identifier is placed in here
1.162 +LOCAL_D TInt threadArray[KTestArraySize];
1.163 +
1.164 +LOCAL_C TInt myThreadEntryPoint(TAny*)
1.165 +//
1.166 +// myThread tests
1.167 +//
1.168 + {
1.169 +
1.170 + __UHEAP_MARK;
1.171 + RTest test(_L("Separate thread tests"));
1.172 + test.Title();
1.173 + test.Start(_L("Create semaphore"));
1.174 + RTimer t;
1.175 + TInt ret=t.CreateLocal();
1.176 + test(ret==KErrNone);
1.177 +//
1.178 + test.Next(_L("Install scheduler"));
1.179 + MyManager* pManager=new MyManager;
1.180 + CActiveScheduler::Install(pManager);
1.181 +//
1.182 + test.Next(_L("Create active objects"));
1.183 + myThreadTimer* pLowest=new myThreadTimer(eLowest, eLowest);
1.184 + test(pLowest!=NULL);
1.185 + myThreadTimer* pLow=new myThreadTimer(eLow, eLow);
1.186 + test(pLow!=NULL);
1.187 + myThreadTimer* pNone=new myThreadTimer(eNone, eNone);
1.188 + test(pNone!=NULL);
1.189 + myThreadTimer* pHigh=new myThreadTimer(eHigh, eHigh);
1.190 + test(pHigh!=NULL);
1.191 + myThreadTimer* pHigh2=new myThreadTimer(eHigh, eHigh+2);
1.192 + test(pHigh2!=NULL);
1.193 + myThreadTimer* pHigh3=new myThreadTimer(eHigh, eHigh+3);
1.194 + test(pHigh3!=NULL);
1.195 + myThreadTimer* pHighest=new myThreadTimer(eHighest, eHighest);
1.196 + test(pHighest!=NULL);
1.197 +//
1.198 + test.Next(_L("Test low is scheduled before lowest"));
1.199 + myThreadTimer::SetNum(2);
1.200 + pLowest->Start();
1.201 + pLowest->After(0);
1.202 + pLow->Start();
1.203 + pLow->After(0);
1.204 + TRequestStatus s;
1.205 + t.After(s,100000);
1.206 + test(s==KRequestPending);
1.207 + User::WaitForRequest(s);
1.208 + CActiveScheduler::Start();
1.209 + test(threadArray[0]==eLow && threadArray[1]==eLowest);
1.210 +//
1.211 + test.Next(_L("Test none is scheduled before low"));
1.212 + myThreadTimer::SetNum(2);
1.213 + pLow->After(0);
1.214 + pNone->Start();
1.215 + pNone->After(0);
1.216 + t.After(s,100000);
1.217 + test(s==KRequestPending);
1.218 + User::WaitForRequest(s);
1.219 + CActiveScheduler::Start();
1.220 + test(threadArray[0]==eNone && threadArray[1]==eLow);
1.221 +//
1.222 + test.Next(_L("Test high is scheduled before none"));
1.223 + myThreadTimer::SetNum(2);
1.224 + pHigh->Start();
1.225 + pHigh->After(0);
1.226 + pNone->After(0);
1.227 + t.After(s, 100000);
1.228 + test(s==KRequestPending);
1.229 + User::WaitForRequest(s);
1.230 + CActiveScheduler::Start();
1.231 + test(threadArray[0]==eHigh && threadArray[1]==eNone);
1.232 +//
1.233 + test.Next(_L("Test highest is scheduled before high"));
1.234 + myThreadTimer::SetNum(2);
1.235 + pHighest->Start();
1.236 + pHighest->After(0);
1.237 + pHigh->After(0);
1.238 + t.After(s, 100000);
1.239 + test(s==KRequestPending);
1.240 + User::WaitForRequest(s);
1.241 + CActiveScheduler::Start();
1.242 + test(threadArray[0]==eHighest && threadArray[1]==eHigh);
1.243 +//
1.244 + test.Next(_L("Test objects are scheduled according to priority"));
1.245 + myThreadTimer::SetNum(5);
1.246 + pLowest->After(0);
1.247 + pLow->After(0);
1.248 + pNone->After(0);
1.249 + pHigh->After(0);
1.250 + pHighest->After(0);
1.251 + t.After(s, 100000);
1.252 + test(s==KRequestPending);
1.253 + User::WaitForRequest(s);
1.254 + CActiveScheduler::Start();
1.255 + test(threadArray[0]==eHighest && threadArray[1]==eHigh && threadArray[2]==eNone &&
1.256 + threadArray[3]==eLow && threadArray[4]==eLowest);
1.257 +//
1.258 + test.Next(_L("Test objects are scheduled according to timer expiry"));
1.259 + myThreadTimer::SetNum(5);
1.260 + pLowest->After(0);
1.261 + pLow->After(500000);
1.262 + pNone->After(1000000);
1.263 + pHigh->After(1500000);
1.264 + pHighest->After(2000000);
1.265 + CActiveScheduler::Start();
1.266 + test(threadArray[4]==eHighest && threadArray[3]==eHigh && threadArray[2]==eNone &&
1.267 + threadArray[1]==eLow && threadArray[0]==eLowest);
1.268 +//
1.269 + test.Next(_L("Test with some objects having the same priority"));
1.270 + myThreadTimer::SetNum(7);
1.271 + pLowest->After(0);
1.272 + pLow->After(0);
1.273 + pNone->After(0);
1.274 + pHigh->After(0);
1.275 + pHigh2->Start();
1.276 + pHigh2->After(0);
1.277 + pHigh3->Start();
1.278 + pHigh3->After(0);
1.279 + pHighest->After(0);
1.280 + t.After(s, 100000);
1.281 + test(s==KRequestPending);
1.282 + User::WaitForRequest(s);
1.283 + CActiveScheduler::Start();
1.284 + test(threadArray[0]==eHighest && threadArray[1]==eHigh && threadArray[2]==eHigh+2 &&
1.285 + threadArray[3]==eHigh+3 && threadArray[4]==eNone && threadArray[5]==eLow && threadArray[6]==eLowest);
1.286 +//
1.287 + test.Next(_L("Tidying up"));
1.288 + delete pManager;
1.289 + delete pLowest;
1.290 + delete pLow;
1.291 + delete pNone;
1.292 + delete pHigh;
1.293 + delete pHigh2;
1.294 + delete pHigh3;
1.295 + delete pHighest;
1.296 + test.Close();
1.297 + __UHEAP_MARKEND;
1.298 + threadSemaphore.Signal();
1.299 + return(KErrNone);
1.300 + }
1.301 +
1.302 +LOCAL_D TInt panicThread(TAny* aDirective)
1.303 +//
1.304 +// Test thread which panics
1.305 +//
1.306 + {
1.307 + // cause panics in various ways depending upon aDirective
1.308 + MyManager* pManager=new MyManager;
1.309 +
1.310 + switch((TInt)aDirective)
1.311 + {
1.312 + case EStartUninstalled:
1.313 + CActiveScheduler::Start(); // Start an uninstalled active schedler
1.314 + break;
1.315 + case EInstallTwice:
1.316 + CActiveScheduler::Install(pManager); // Install the scheduler twice
1.317 + CActiveScheduler::Install(pManager);
1.318 + break;
1.319 + case EStopTwice:
1.320 + CActiveScheduler::Install(pManager); // Stop a scheduler twice
1.321 + CActiveScheduler::Stop();
1.322 + CActiveScheduler::Stop();
1.323 + break;
1.324 + case EStopUninstalled:
1.325 + CActiveScheduler::Stop(); // Stop an uninstalled active scheduler
1.326 + break;
1.327 + case ESetActiveTwice:
1.328 + {
1.329 +//
1.330 +// Set an active object to active twice
1.331 +//
1.332 + myTimer* pTimer=new myTimer(eNone,eNone);
1.333 + CActiveScheduler::Install(pManager);
1.334 + CActiveScheduler::Add(pTimer);
1.335 + pTimer->Setactive();
1.336 + pTimer->Setactive();
1.337 + }
1.338 + break;
1.339 + case EAddToUninstalled:
1.340 + {
1.341 +//
1.342 +// Add an active object to an uninstalled scheduler
1.343 +//
1.344 + myTimer* pTimer=new myTimer(eNone,eNone);
1.345 + CActiveScheduler::Add(pTimer);
1.346 + }
1.347 + break;
1.348 + case EAddNull:
1.349 +//
1.350 +// Add Null to the scheduling queue
1.351 +//
1.352 + CActiveScheduler::Install(pManager);
1.353 + CActiveScheduler::Add(NULL);
1.354 + break;
1.355 + case EAddTwice:
1.356 + {
1.357 +//
1.358 +// Add the same object twice to the scheduling queue
1.359 +//
1.360 + myTimer* pTimer=new myTimer(eNone,eNone);
1.361 + CActiveScheduler::Install(pManager);
1.362 + CActiveScheduler::Add(pTimer);
1.363 + CActiveScheduler::Add(pTimer);
1.364 + }
1.365 + break;
1.366 + case ECreateStray:
1.367 + {
1.368 +//
1.369 +// Create a stray signal
1.370 +//
1.371 + CActiveScheduler::Install(pManager);
1.372 + new CreateStray(1);
1.373 + CActiveScheduler::Start();
1.374 + }
1.375 + break;
1.376 + case ERequestUnadded:
1.377 + {
1.378 +//
1.379 +// Make a request of an active object not added to the scheduling queue
1.380 +//
1.381 + CActiveScheduler::Install(pManager);
1.382 + myTimer* pTimer=new myTimer(eNone,eNone);
1.383 + pTimer->Setactive();
1.384 + }
1.385 + break;
1.386 + case EStraySignalNoKRequestPending:
1.387 + {
1.388 + CActiveScheduler::Install(pManager);
1.389 + myStray* pStray = new myStray(eNone);
1.390 + CActiveScheduler::Add(pStray);
1.391 + pStray->Start1();
1.392 + CActiveScheduler::Start();
1.393 + }
1.394 + break;
1.395 + case EStraySignalNoSetActive:
1.396 + {
1.397 + CActiveScheduler::Install(pManager);
1.398 + myStray* pStray = new myStray(eNone);
1.399 + CActiveScheduler::Add(pStray);
1.400 + pStray->Start2();
1.401 + CActiveScheduler::Start();
1.402 + }
1.403 + break;
1.404 + case ENormal:
1.405 + default:
1.406 + break;
1.407 + }
1.408 + delete pManager;
1.409 + return(KPanicThreadRet);
1.410 + }
1.411 +
1.412 +void myTimer::RunL()
1.413 +//
1.414 +// Handle the timer completion
1.415 +//
1.416 + {
1.417 +
1.418 + if (iIdentifier==KLeaveCode) // Used to test that the request manager error() method is called
1.419 + User::Leave(KmyErrorNum);
1.420 + if (iIdentifier==KCancelCode) // Used to test cancelling an object
1.421 + gTimer->Cancel();
1.422 + order[iCount++]=iIdentifier;
1.423 + if (iCount>=iNum)
1.424 + CActiveScheduler::Stop();
1.425 + }
1.426 +
1.427 +void myTimer::Start()
1.428 +//
1.429 +// Start a timer
1.430 +//
1.431 + {
1.432 +
1.433 + ConstructL();
1.434 + CActiveScheduler::Add(this);
1.435 + }
1.436 +
1.437 +void myThreadTimer::RunL()
1.438 +//
1.439 +// Handle timer completion
1.440 +//
1.441 + {
1.442 +
1.443 + threadArray[iCount++]=iIdentifier;
1.444 + if(iCount>=iNum)
1.445 + CActiveScheduler::Stop();
1.446 + }
1.447 +
1.448 +void myThreadTimer::Start()
1.449 +//
1.450 +// Start a timer
1.451 +//
1.452 + {
1.453 +
1.454 + ConstructL();
1.455 + CActiveScheduler::Add(this);
1.456 + }
1.457 +
1.458 +CreateStray::CreateStray(TInt aPriority)
1.459 +//
1.460 +// Constructor
1.461 +//
1.462 + : CActive(aPriority)
1.463 + {
1.464 +
1.465 + iTimer.CreateLocal();
1.466 + CActiveScheduler::Add(this);
1.467 + iTimer.After(iStatus, 1000000);
1.468 + }
1.469 +
1.470 +void TSecdulerTester::Test1()
1.471 +//
1.472 +// Test 1
1.473 +//
1.474 + {
1.475 +
1.476 +//
1.477 +// Test the panics
1.478 +//
1.479 +
1.480 + RThread thread;
1.481 + TRequestStatus stat;
1.482 +//
1.483 + test.Start(_L("First test normal thread termination"));
1.484 + TInt r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ENormal);
1.485 + test(r==KErrNone);
1.486 + thread.Logon(stat);
1.487 + thread.Resume();
1.488 + User::WaitForRequest(stat);
1.489 + test(thread.ExitCategory().Compare(_L("Kill"))==0);
1.490 + test(thread.ExitReason()==KPanicThreadRet);
1.491 + test(thread.ExitType()==EExitKill);
1.492 + CLOSE_AND_WAIT(thread);
1.493 +//
1.494 + test.Next(_L("Starting an uninstalled scheduler panics"));
1.495 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStartUninstalled);
1.496 + test(r==KErrNone);
1.497 + thread.Logon(stat);
1.498 + thread.Resume();
1.499 + User::WaitForRequest(stat);
1.500 + test(thread.ExitReason()==EReqManagerDoesNotExist);
1.501 + test(thread.ExitType()==EExitPanic);
1.502 + CLOSE_AND_WAIT(thread);
1.503 +//
1.504 + test.Next(_L("Installing the scheduler twice panics"));
1.505 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EInstallTwice);
1.506 + test(r==KErrNone);
1.507 + thread.Logon(stat);
1.508 + thread.Resume();
1.509 + User::WaitForRequest(stat);
1.510 + test(thread.ExitReason()==EReqManagerAlreadyExists);
1.511 + test(thread.ExitType()==EExitPanic);
1.512 + CLOSE_AND_WAIT(thread);
1.513 +//
1.514 + test.Next(_L("Stopping the scheduler twice panics"));
1.515 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopTwice);
1.516 + test(r==KErrNone);
1.517 + thread.Logon(stat);
1.518 + thread.Resume();
1.519 + User::WaitForRequest(stat);
1.520 + test(thread.ExitReason()==EReqTooManyStops);
1.521 + test(thread.ExitType()==EExitPanic);
1.522 + CLOSE_AND_WAIT(thread);
1.523 +//
1.524 + test.Next(_L("Stopping an uninstalled scheduler panics"));
1.525 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopUninstalled);
1.526 + test(r==KErrNone);
1.527 + thread.Logon(stat);
1.528 + thread.Resume();
1.529 + User::WaitForRequest(stat);
1.530 + test(thread.ExitReason()==EReqManagerDoesNotExist);
1.531 + test(thread.ExitType()==EExitPanic);
1.532 + CLOSE_AND_WAIT(thread);
1.533 +//
1.534 + test.Next(_L("Setting an active object to active twice panics"));
1.535 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ESetActiveTwice);
1.536 + test(r==KErrNone);
1.537 + thread.Logon(stat);
1.538 + thread.Resume();
1.539 + User::WaitForRequest(stat);
1.540 + test(thread.ExitReason()==EReqAlreadyActive);
1.541 + test(thread.ExitType()==EExitPanic);
1.542 + CLOSE_AND_WAIT(thread);
1.543 +//
1.544 + test.Next(_L("Adding an active object to an uninstalled scheduler panics"));
1.545 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddToUninstalled);
1.546 + test(r==KErrNone);
1.547 + thread.Logon(stat);
1.548 + thread.Resume();
1.549 + User::WaitForRequest(stat);
1.550 + test(thread.ExitReason()==EReqManagerDoesNotExist);
1.551 + test(thread.ExitType()==EExitPanic);
1.552 + CLOSE_AND_WAIT(thread);
1.553 +//
1.554 + test.Next(_L("Adding NULL panics"));
1.555 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddNull);
1.556 + test(r==KErrNone);
1.557 + thread.Logon(stat);
1.558 + thread.Resume();
1.559 + User::WaitForRequest(stat);
1.560 + test(thread.ExitReason()==EReqNull);
1.561 + test(thread.ExitType()==EExitPanic);
1.562 + CLOSE_AND_WAIT(thread);
1.563 +//
1.564 + test.Next(_L("Adding an active object twice panics"));
1.565 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddTwice);
1.566 + test(r==KErrNone);
1.567 + thread.Logon(stat);
1.568 + thread.Resume();
1.569 + User::WaitForRequest(stat);
1.570 + test(thread.ExitReason()==EReqAlreadyAdded);
1.571 + test(thread.ExitType()==EExitPanic);
1.572 + CLOSE_AND_WAIT(thread);
1.573 +//
1.574 + test.Next(_L("A stray signal causes a panic"));
1.575 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ECreateStray);
1.576 + test(r==KErrNone);
1.577 + thread.Logon(stat);
1.578 + thread.Resume();
1.579 + User::WaitForRequest(stat);
1.580 + test(thread.ExitReason()==EReqStrayEvent);
1.581 + test(thread.ExitType()==EExitPanic);
1.582 + CLOSE_AND_WAIT(thread);
1.583 +//
1.584 + test.Next(_L("Making a request on an unadded active object panics"));
1.585 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ERequestUnadded);
1.586 + test(r==KErrNone);
1.587 + thread.Logon(stat);
1.588 + thread.Resume();
1.589 + User::WaitForRequest(stat);
1.590 + test(thread.ExitReason()==EActiveNotAdded);
1.591 + test(thread.ExitType()==EExitPanic);
1.592 + CLOSE_AND_WAIT(thread);
1.593 +//
1.594 + test.Next(_L("The service provider does not set the status to KRequestPending"));
1.595 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStraySignalNoKRequestPending);
1.596 + test(r==KErrNone);
1.597 + thread.Logon(stat);
1.598 + thread.Resume();
1.599 + User::WaitForRequest(stat);
1.600 +#ifdef _DEBUG
1.601 + //this might fail if we're using a UREL euser
1.602 + test(thread.ExitReason()==EReqStrayEvent);
1.603 + test(thread.ExitType()==EExitPanic);
1.604 +#else
1.605 + test(thread.ExitCategory().Compare(_L("Kill"))==0);
1.606 + test(thread.ExitReason()==KPanicThreadRet);
1.607 + test(thread.ExitType()==EExitKill);
1.608 +#endif
1.609 + CLOSE_AND_WAIT(thread);
1.610 +//
1.611 +#ifdef _DEBUG
1.612 + //this might fail if we're using a UREL euser
1.613 + test.Next(_L("The active object does not call SetActive"));
1.614 + r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStraySignalNoSetActive);
1.615 + test(r==KErrNone);
1.616 + thread.Logon(stat);
1.617 + thread.Resume();
1.618 + User::WaitForRequest(stat);
1.619 + test(thread.ExitReason()==EReqStrayEvent);
1.620 + test(thread.ExitType()==EExitPanic);
1.621 + CLOSE_AND_WAIT(thread);
1.622 +#endif
1.623 +//
1.624 + test.End();
1.625 + }
1.626 +
1.627 +void TSecdulerTester::Test2()
1.628 +//
1.629 +// Test 2
1.630 +//
1.631 + {
1.632 +
1.633 + test.Start(_L("Create timer"));
1.634 + RTimer t;
1.635 + TInt ret=t.CreateLocal();
1.636 + test(ret==KErrNone);
1.637 + TRequestStatus s;
1.638 +//
1.639 + test.Next(_L("Test low is scheduled before lowest when timing equal"));
1.640 + myTimer::SetNum(2);
1.641 + pLowest->After(0);
1.642 + pLow->After(0);
1.643 + t.After(s, 100000);
1.644 + test(s==KRequestPending);
1.645 + User::WaitForRequest(s);
1.646 + CActiveScheduler::Start();
1.647 + test(order[0]==eLow && order[1]==eLowest);
1.648 +//
1.649 + test.Next(_L("Test low is not before lowest when it expires later"));
1.650 + myTimer::SetNum(2);
1.651 + pLowest->After(0);
1.652 + pLow->After(1000000);
1.653 + CActiveScheduler::Start();
1.654 + test(order[0]==eLowest && order[1]==eLow);
1.655 +//
1.656 + test.Next(_L("Test none is scheduled before low"));
1.657 + myTimer::SetNum(2);
1.658 + pLow->After(0);
1.659 + pNone->After(0);
1.660 + t.After(s, 100000);
1.661 + test(s==KRequestPending);
1.662 + User::WaitForRequest(s);
1.663 + CActiveScheduler::Start();
1.664 + test(order[0]==eNone && order[1]==eLow);
1.665 +//
1.666 + test.Next(_L("Test none is not before low when it expires later"));
1.667 + myTimer::SetNum(2);
1.668 + pLow->After(0);
1.669 + pNone->After(1000000);
1.670 + CActiveScheduler::Start();
1.671 + test(order[0]==eLow && order[1]==eNone);
1.672 +//
1.673 + test.Next(_L("Test high is scheduled before none"));
1.674 + myTimer::SetNum(2);
1.675 + pHigh->After(0);
1.676 + pNone->After(0);
1.677 + t.After(s, 100000);
1.678 + test(s==KRequestPending);
1.679 + User::WaitForRequest(s);
1.680 + CActiveScheduler::Start();
1.681 + test(order[0]==eHigh && order[1]==eNone);
1.682 +//
1.683 + test.Next(_L("Test high is not before none when it expires later"));
1.684 + myTimer::SetNum(2);
1.685 + pHigh->After(1000000);
1.686 + pNone->After(0);
1.687 + CActiveScheduler::Start();
1.688 + test(order[0]==eNone && order[1]==eHigh);
1.689 +//
1.690 + test.Next(_L("Test highest is scheduled before high"));
1.691 + myTimer::SetNum(2);
1.692 + pHighest->After(0);
1.693 + pHigh->After(0);
1.694 + t.After(s, 100000);
1.695 + test(s==KRequestPending);
1.696 + User::WaitForRequest(s);
1.697 + CActiveScheduler::Start();
1.698 + test(order[0]==eHighest && order[1]==eHigh);
1.699 +//
1.700 + test.Next(_L("Test highest is not before high when it expires later"));
1.701 + myTimer::SetNum(2);
1.702 + pHighest->After(1000000);
1.703 + pHigh->After(0);
1.704 + CActiveScheduler::Start();
1.705 + test(order[0]==eHigh && order[1]==eHighest);
1.706 +//
1.707 + test.Next(_L("Test all objects are scheduled in priority order"));
1.708 + myTimer::SetNum(5);
1.709 + pLowest->After(0);
1.710 + pLow->After(0);
1.711 + pNone->After(0);
1.712 + pHigh->After(0);
1.713 + pHighest->After(0);
1.714 + t.After(s, 100000);
1.715 + test(s==KRequestPending);
1.716 + User::WaitForRequest(s);
1.717 + CActiveScheduler::Start();
1.718 + test(order[0]==eHighest && order[1]==eHigh && order[2]==eNone && order[3]==eLow && order[4]==eLowest);
1.719 +//
1.720 + test.Next(_L("Test objects are scheduled according to expiry of timers"));
1.721 + myTimer::SetNum(5);
1.722 + pLowest->After(0);
1.723 + pLow->After(500000);
1.724 + pNone->After(1000000);
1.725 + pHigh->After(1500000);
1.726 + pHighest->After(2000000);
1.727 + CActiveScheduler::Start();
1.728 + test(order[4]==eHighest && order[3]==eHigh && order[2]==eNone && order[1]==eLow && order[0]==eLowest);
1.729 +//
1.730 + test.Next(_L("Test with some objects having the same priority"));
1.731 + myTimer::SetNum(7);
1.732 + pLowest->After(0);
1.733 + pLow->After(0);
1.734 + pNone->After(0);
1.735 + pHigh->After(0);
1.736 + pHigh2->After(0);
1.737 + pHigh3->After(0);
1.738 + pHighest->After(0);
1.739 + t.After(s, 100000);
1.740 + test(s==KRequestPending);
1.741 + User::WaitForRequest(s);
1.742 + CActiveScheduler::Start();
1.743 + test(order[0]==eHighest && order[1]==eHigh && order[2]==eHigh+2 && order[3]==eHigh+3 && order[4]==eNone && order[5]==eLow && order[6]==eLowest);
1.744 +//
1.745 + test.End();
1.746 + }
1.747 +
1.748 +void TSecdulerTester::Test3()
1.749 +//
1.750 +// Test 3
1.751 +//
1.752 + {
1.753 +
1.754 +//
1.755 +// Test that a leave in a Run method calls the requestmanager error() method
1.756 +//
1.757 + myTimer* pTimer=new myTimer(0, KLeaveCode);
1.758 + pTimer->Start();
1.759 + pTimer->After(100000);
1.760 + TRAPD(ret,CActiveScheduler::Start());
1.761 + test(ret==KmyErrorNum);
1.762 +//
1.763 +// Test cancelling an object
1.764 +// Without the cancel the schedule order should be: pTimer1, gTimer, pTimer3
1.765 +// gTimer is cancelled so should not be scheduled
1.766 +//
1.767 + myTimer::SetNum(2);
1.768 + myTimer* pTimer2=new myTimer(eHighest,KCancelCode);
1.769 + myTimer* pTimer3=new myTimer(eLowest,eLowest);
1.770 + pTimer2->Start();
1.771 + pTimer2->After(100000);
1.772 + gTimer->Start();
1.773 + gTimer->After(1000000);
1.774 + pTimer3->Start();
1.775 + pTimer3->After(2000000);
1.776 + CActiveScheduler::Start();
1.777 + test(order[0]==KCancelCode && order[1]==eLowest);
1.778 + delete pTimer;
1.779 + delete pTimer2;
1.780 + delete pTimer3;
1.781 + }
1.782 +
1.783 +void TSecdulerTester::Test4()
1.784 +//
1.785 +// Create a thread with its own scheduler
1.786 +//
1.787 + {
1.788 +
1.789 + threadSemaphore.CreateLocal(0);
1.790 + RThread myThread;
1.791 + test(myThread.Create(_L("myThread"),myThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL)==KErrNone);
1.792 + myThread.Resume();
1.793 + myThread.Close();
1.794 + Test2();
1.795 + threadSemaphore.Wait();
1.796 + User::After(100000);
1.797 + }
1.798 +
1.799 +GLDEF_C TInt E32Main()
1.800 + {
1.801 +
1.802 + // don't want just in time debugging as we trap panics
1.803 + TBool justInTime=User::JustInTime();
1.804 + User::SetJustInTime(EFalse);
1.805 +
1.806 + test.Title();
1.807 + __UHEAP_MARK;
1.808 +//
1.809 + test.Start(_L("Test1"));
1.810 + TSecdulerTester sched;
1.811 + sched.Test1();
1.812 + MyManager* pManager=new MyManager;
1.813 + test(pManager!=NULL);
1.814 + CActiveScheduler::Install(pManager);
1.815 + test(CActiveScheduler::Current()==pManager);
1.816 + MyManager* pManager2=new MyManager;
1.817 + test(pManager2!=NULL);
1.818 + delete pManager2;
1.819 + test(CActiveScheduler::Current()==pManager);
1.820 + pLowest=new myTimer(eLowest,eLowest);
1.821 + test(pLowest!=NULL);
1.822 + pLow=new myTimer(eLow,eLow);
1.823 + test(pLow!=NULL);
1.824 + pNone=new myTimer(eNone,eNone);
1.825 + test(pNone!=NULL);
1.826 + pHigh=new myTimer(eHigh,eHigh);
1.827 + test(pHigh!=NULL);
1.828 + pHigh2=new myTimer(eHigh,eHigh+2);
1.829 + test(pHigh2!=NULL);
1.830 + pHigh3=new myTimer(eHigh,eHigh+3);
1.831 + test(pHigh3!=NULL);
1.832 + pHighest=new myTimer(eHighest,eHighest);
1.833 + test(pHighest!=NULL);
1.834 + pLowest->Start();
1.835 + pLow->Start();
1.836 + pNone->Start();
1.837 + pHigh->Start();
1.838 + pHigh2->Start();
1.839 + pHigh3->Start();
1.840 + pHighest->Start();
1.841 +//
1.842 + test.Next(_L("Test2"));
1.843 + sched.Test2();
1.844 + User::Check();
1.845 +//
1.846 + test.Next(_L("Test3"));
1.847 + gTimer=new myTimer(eNone, KgTimerID);
1.848 + sched.Test3();
1.849 +//
1.850 + test.Next(_L("Test4"));
1.851 + sched.Test4();
1.852 + delete gTimer;
1.853 + User::Check();
1.854 + delete pManager;
1.855 + delete pLowest;
1.856 + delete pLow;
1.857 + delete pNone;
1.858 + delete pHigh;
1.859 + delete pHigh2;
1.860 + delete pHigh3;
1.861 + delete pHighest;
1.862 +//
1.863 + test.End();
1.864 + __UHEAP_MARKEND;
1.865 +
1.866 + User::SetJustInTime(justInTime);
1.867 + return(KErrNone);
1.868 + }