kerneltest/e32test/active/t_cact.cpp
changeset 0 a41df078684a
child 271 dc268b18d709
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32test\active\t_cact.cpp
       
    15 // Overview:
       
    16 // Test the CActiveScheduler class, including scheduling priority, thread 
       
    17 // panics and cancelling objects attached to the scheduler. 
       
    18 // API Information:
       
    19 // CActiveScheduler 
       
    20 // Details:
       
    21 // - Verify the thread is panicked when one of the following programming errors occurs:
       
    22 // - start an uninstalled scheduler
       
    23 // - install a scheduler twice
       
    24 // - stop the scheduler twice 
       
    25 // - stop an uninstalled scheduler
       
    26 // - set active an active object twice
       
    27 // - add an active object to an uninstalled scheduler
       
    28 // - add a NULL pointer to the scheduler
       
    29 // - add an active object twice
       
    30 // - thread gets a stray signal
       
    31 // - make request on an un-added active object
       
    32 // - Create timers with different priorities
       
    33 // - Check the timers are scheduled according to expiration time
       
    34 // - Check the timers are scheduled in order of their priority when they expire at the
       
    35 // same time
       
    36 // - Check the timers are scheduled in order of the addition to the scheduler when
       
    37 // they expire at the same time and they have the same priority
       
    38 // - Verify that a leave in RunL method not handled by the active object calls the active 
       
    39 // scheduler's Error method
       
    40 // - Test a cancelled timer will not be scheduled 
       
    41 // - Create a thread with its own heap and test that timers are scheduled in the order of
       
    42 // their expiration time, priority and order of addition to the scheduler
       
    43 // - Check the heap is not corrupted by all the tests
       
    44 // Platforms/Drives/Compatibility:
       
    45 // All
       
    46 // Assumptions/Requirement/Pre-requisites:
       
    47 // Failures and causes:
       
    48 // Base Port information:
       
    49 // 
       
    50 //
       
    51 
       
    52 #include <e32test.h>
       
    53 #include <e32panic.h>
       
    54 
       
    55 const TInt KmyErrorNum=999;
       
    56 const TInt KLeaveCode=1234;  
       
    57 const TInt KgTimerID=4321;
       
    58 const TInt KCancelCode=1111;
       
    59 const TInt KTestArraySize=10;
       
    60 const TInt KPanicThreadRet=2222;
       
    61 const TInt KHeapSize=0x2000;
       
    62 
       
    63 enum TActivePriority {eLowest=-100,eLow=-1,eNone=0,eHigh=1,eHighest=100};
       
    64 enum TDirective {EStartUninstalled,EInstallTwice,EStopTwice,EStopUninstalled,ESetActiveTwice,
       
    65 				 EAddToUninstalled,EAddNull,EAddTwice,ECreateStray,ERequestUnadded,EStraySignalNoKRequestPending,EStraySignalNoSetActive,ENormal};
       
    66 
       
    67 class TSecdulerTester
       
    68 	{
       
    69 public:
       
    70 	void Test1();
       
    71 	void Test2();
       
    72 	void Test3();
       
    73 	void Test4();
       
    74 	};
       
    75 
       
    76 class MyManager : public CActiveScheduler
       
    77 	{
       
    78 public:
       
    79 	virtual void Error(TInt anError) const {CActiveScheduler::Halt(anError);}
       
    80 	};
       
    81 
       
    82 class myTimer : public CTimer
       
    83 	{
       
    84 public:
       
    85 	myTimer(const TInt aPriority, const TInt anIdentifier):CTimer(aPriority){iIdentifier=anIdentifier;}
       
    86 	virtual void RunL();
       
    87 	void Start();		  
       
    88 	void Setactive() {SetActive();}
       
    89 	static void SetNum(const TInt aNum) {iNum=aNum; iCount=0;}
       
    90 private:   
       
    91 	TInt iIdentifier;
       
    92 	static TInt iCount;
       
    93 	static TInt iNum;
       
    94 	};
       
    95 
       
    96 class myThreadTimer : public CTimer
       
    97 	{
       
    98 public:
       
    99 	myThreadTimer(const TInt aPriority, const TInt anIdentifier):CTimer(aPriority){iIdentifier=anIdentifier;}
       
   100 	virtual void RunL();
       
   101 	static void SetNum(const TInt aNum) {iNum=aNum; iCount=0;}
       
   102 	void Start();
       
   103 private:
       
   104 	TInt iIdentifier;
       
   105 	static TInt iCount;
       
   106 	static TInt iNum;
       
   107 	};
       
   108 
       
   109 class CreateStray : public CActive
       
   110 	{
       
   111 public:
       
   112 	CreateStray(TInt aPriority);
       
   113 	void DoCancel() {}
       
   114 	void RunL() {}
       
   115 private:
       
   116 	RTimer iTimer;
       
   117 	};
       
   118 
       
   119 class myStray : public CActive
       
   120 	{
       
   121 public:
       
   122 	myStray(TInt aPriority) : CActive(aPriority) {};
       
   123 	void DoCancel() {}
       
   124 	void RunL() { CActiveScheduler::Stop(); }
       
   125 	void Start1();
       
   126 	void Start2();
       
   127 	};
       
   128 
       
   129 void myStray::Start1()
       
   130 	{
       
   131 	TRequestStatus* s=&iStatus;
       
   132 	SetActive();
       
   133 	RThread().RequestComplete(s,KErrNone);
       
   134 	}
       
   135 
       
   136 void myStray::Start2()
       
   137 	{
       
   138 	TRequestStatus* s=&iStatus;
       
   139 	iStatus=KRequestPending;
       
   140 	User::RequestComplete(s,KErrNone);
       
   141 	}
       
   142 
       
   143 TInt myTimer::iCount;
       
   144 TInt myTimer::iNum;
       
   145 TInt myThreadTimer::iCount;
       
   146 TInt myThreadTimer::iNum;
       
   147 
       
   148 LOCAL_D RTest test(_L("T_CACT"));
       
   149 LOCAL_D myTimer* gTimer; // This is cancelled from within the run method 
       
   150 LOCAL_D RSemaphore threadSemaphore;
       
   151 LOCAL_D myTimer* pLowest=NULL;
       
   152 LOCAL_D myTimer* pLow=NULL;
       
   153 LOCAL_D myTimer* pNone=NULL;
       
   154 LOCAL_D myTimer* pHigh=NULL;
       
   155 LOCAL_D myTimer* pHigh2=NULL;
       
   156 LOCAL_D myTimer* pHigh3=NULL;
       
   157 LOCAL_D myTimer* pHighest=NULL;
       
   158 LOCAL_D TInt order[KTestArraySize]; // When a timer expires its identifier is placed in here
       
   159 LOCAL_D TInt threadArray[KTestArraySize];
       
   160 
       
   161 LOCAL_C TInt myThreadEntryPoint(TAny*)
       
   162 //
       
   163 // myThread tests 
       
   164 //
       
   165 	{
       
   166 
       
   167 	__UHEAP_MARK;
       
   168 	RTest test(_L("Separate thread tests"));
       
   169 	test.Title();
       
   170 	test.Start(_L("Create semaphore"));
       
   171 	RTimer t;
       
   172 	TInt ret=t.CreateLocal();
       
   173 	test(ret==KErrNone);
       
   174 //
       
   175 	test.Next(_L("Install scheduler"));
       
   176 	MyManager* pManager=new MyManager;
       
   177 	CActiveScheduler::Install(pManager);
       
   178 //
       
   179 	test.Next(_L("Create active objects"));
       
   180 	myThreadTimer* pLowest=new myThreadTimer(eLowest, eLowest);
       
   181 	test(pLowest!=NULL);
       
   182 	myThreadTimer* pLow=new myThreadTimer(eLow, eLow);
       
   183 	test(pLow!=NULL);
       
   184 	myThreadTimer* pNone=new myThreadTimer(eNone, eNone);
       
   185 	test(pNone!=NULL);
       
   186 	myThreadTimer* pHigh=new myThreadTimer(eHigh, eHigh);
       
   187 	test(pHigh!=NULL);
       
   188 	myThreadTimer* pHigh2=new myThreadTimer(eHigh, eHigh+2);
       
   189 	test(pHigh2!=NULL);
       
   190 	myThreadTimer* pHigh3=new myThreadTimer(eHigh, eHigh+3);
       
   191 	test(pHigh3!=NULL);
       
   192 	myThreadTimer* pHighest=new myThreadTimer(eHighest, eHighest);
       
   193 	test(pHighest!=NULL);
       
   194 //
       
   195 	test.Next(_L("Test low is scheduled before lowest"));
       
   196 	myThreadTimer::SetNum(2);
       
   197 	pLowest->Start();
       
   198 	pLowest->After(0);
       
   199 	pLow->Start();
       
   200 	pLow->After(0);
       
   201 	TRequestStatus s;
       
   202 	t.After(s,100000);
       
   203 	test(s==KRequestPending);
       
   204 	User::WaitForRequest(s);
       
   205 	CActiveScheduler::Start();
       
   206 	test(threadArray[0]==eLow && threadArray[1]==eLowest);
       
   207 //
       
   208 	test.Next(_L("Test none is scheduled before low"));
       
   209 	myThreadTimer::SetNum(2);
       
   210 	pLow->After(0);
       
   211 	pNone->Start();
       
   212 	pNone->After(0);
       
   213 	t.After(s,100000);
       
   214 	test(s==KRequestPending);
       
   215 	User::WaitForRequest(s);
       
   216 	CActiveScheduler::Start();
       
   217 	test(threadArray[0]==eNone && threadArray[1]==eLow);
       
   218 //
       
   219 	test.Next(_L("Test high is scheduled before none"));
       
   220 	myThreadTimer::SetNum(2);
       
   221 	pHigh->Start();
       
   222 	pHigh->After(0);
       
   223 	pNone->After(0);
       
   224 	t.After(s, 100000);
       
   225 	test(s==KRequestPending);
       
   226 	User::WaitForRequest(s);
       
   227 	CActiveScheduler::Start();
       
   228 	test(threadArray[0]==eHigh && threadArray[1]==eNone);
       
   229 //
       
   230 	test.Next(_L("Test highest is scheduled before high"));
       
   231 	myThreadTimer::SetNum(2);
       
   232 	pHighest->Start();
       
   233 	pHighest->After(0);
       
   234 	pHigh->After(0);
       
   235 	t.After(s, 100000);
       
   236 	test(s==KRequestPending);
       
   237 	User::WaitForRequest(s);
       
   238 	CActiveScheduler::Start();
       
   239 	test(threadArray[0]==eHighest && threadArray[1]==eHigh);
       
   240 //
       
   241 	test.Next(_L("Test objects are scheduled according to priority"));
       
   242 	myThreadTimer::SetNum(5);
       
   243 	pLowest->After(0);
       
   244 	pLow->After(0);
       
   245 	pNone->After(0);
       
   246 	pHigh->After(0);
       
   247 	pHighest->After(0);
       
   248 	t.After(s, 100000);
       
   249 	test(s==KRequestPending);
       
   250 	User::WaitForRequest(s);
       
   251 	CActiveScheduler::Start();
       
   252 	test(threadArray[0]==eHighest && threadArray[1]==eHigh && threadArray[2]==eNone && 
       
   253 		 threadArray[3]==eLow && threadArray[4]==eLowest);
       
   254 //
       
   255 	test.Next(_L("Test objects are scheduled according to timer expiry"));
       
   256 	myThreadTimer::SetNum(5);
       
   257 	pLowest->After(0);
       
   258 	pLow->After(500000);
       
   259 	pNone->After(1000000);
       
   260 	pHigh->After(1500000);
       
   261 	pHighest->After(2000000);
       
   262 	CActiveScheduler::Start();
       
   263 	test(threadArray[4]==eHighest && threadArray[3]==eHigh && threadArray[2]==eNone && 
       
   264 		 threadArray[1]==eLow && threadArray[0]==eLowest);
       
   265 //
       
   266 	test.Next(_L("Test with some objects having the same priority"));
       
   267 	myThreadTimer::SetNum(7);
       
   268 	pLowest->After(0);
       
   269 	pLow->After(0);
       
   270 	pNone->After(0);
       
   271 	pHigh->After(0);
       
   272 	pHigh2->Start();
       
   273 	pHigh2->After(0);
       
   274 	pHigh3->Start();
       
   275 	pHigh3->After(0);
       
   276 	pHighest->After(0);
       
   277 	t.After(s, 100000);
       
   278 	test(s==KRequestPending);
       
   279 	User::WaitForRequest(s);
       
   280 	CActiveScheduler::Start();
       
   281 	test(threadArray[0]==eHighest && threadArray[1]==eHigh && threadArray[2]==eHigh+2 && 
       
   282 		 threadArray[3]==eHigh+3 && threadArray[4]==eNone && threadArray[5]==eLow && threadArray[6]==eLowest);
       
   283 //
       
   284 	test.Next(_L("Tidying up"));
       
   285 	delete pManager;
       
   286 	delete pLowest;
       
   287 	delete pLow;
       
   288 	delete pNone;
       
   289 	delete pHigh;
       
   290 	delete pHigh2;
       
   291 	delete pHigh3;
       
   292 	delete pHighest;
       
   293 	test.Close();
       
   294 	__UHEAP_MARKEND;
       
   295 	threadSemaphore.Signal();
       
   296 	return(KErrNone);
       
   297 	}
       
   298 
       
   299 LOCAL_D TInt panicThread(TAny* aDirective)
       
   300 //
       
   301 // Test thread which panics
       
   302 //
       
   303 	{
       
   304 	// cause panics in various ways depending upon aDirective
       
   305 	MyManager* pManager=new MyManager;
       
   306 	
       
   307 	switch((TInt)aDirective)
       
   308 		{
       
   309 	case EStartUninstalled:
       
   310 		CActiveScheduler::Start(); // Start an uninstalled active schedler
       
   311 		break;
       
   312 	case EInstallTwice:
       
   313 		CActiveScheduler::Install(pManager); // Install the scheduler twice
       
   314 		CActiveScheduler::Install(pManager);
       
   315 		break;
       
   316 	case EStopTwice:
       
   317 		CActiveScheduler::Install(pManager); // Stop a scheduler twice
       
   318 		CActiveScheduler::Stop();
       
   319 		CActiveScheduler::Stop();
       
   320 		break;
       
   321 	case EStopUninstalled:
       
   322 		CActiveScheduler::Stop(); // Stop an uninstalled active scheduler
       
   323 		break;
       
   324 	case ESetActiveTwice:
       
   325 		{
       
   326 //
       
   327 // Set an active object to active twice
       
   328 //
       
   329 		myTimer* pTimer=new myTimer(eNone,eNone);
       
   330 		CActiveScheduler::Install(pManager);
       
   331 		CActiveScheduler::Add(pTimer);
       
   332 		pTimer->Setactive();
       
   333 		pTimer->Setactive();
       
   334 		}
       
   335 		break;
       
   336 	case EAddToUninstalled:
       
   337 		{
       
   338 //
       
   339 // Add an active object to an uninstalled scheduler
       
   340 //
       
   341 		myTimer* pTimer=new myTimer(eNone,eNone);
       
   342 		CActiveScheduler::Add(pTimer); 
       
   343 		}
       
   344 		break;
       
   345 	case EAddNull:
       
   346 //
       
   347 // Add Null to the scheduling queue
       
   348 //
       
   349 		CActiveScheduler::Install(pManager);  
       
   350 		CActiveScheduler::Add(NULL);
       
   351 		break;
       
   352 	case EAddTwice:
       
   353 		{
       
   354 //
       
   355 // Add the same object twice to the scheduling queue
       
   356 //
       
   357 		myTimer* pTimer=new myTimer(eNone,eNone);
       
   358 		CActiveScheduler::Install(pManager);  
       
   359 		CActiveScheduler::Add(pTimer);
       
   360 		CActiveScheduler::Add(pTimer);
       
   361 		}
       
   362 		break;
       
   363 	case ECreateStray:
       
   364 		{
       
   365 //
       
   366 // Create a stray signal
       
   367 //
       
   368 		CActiveScheduler::Install(pManager); 
       
   369 		new CreateStray(1);
       
   370 		CActiveScheduler::Start();
       
   371 		}
       
   372 		break;
       
   373 	case ERequestUnadded:
       
   374 		{
       
   375 //
       
   376 // Make a request of an active object not added to the scheduling queue
       
   377 //
       
   378 		CActiveScheduler::Install(pManager);
       
   379 		myTimer* pTimer=new myTimer(eNone,eNone);
       
   380 		pTimer->Setactive();
       
   381 		}
       
   382 		break;
       
   383 	case EStraySignalNoKRequestPending:
       
   384 		{
       
   385 		CActiveScheduler::Install(pManager);
       
   386 		myStray* pStray = new myStray(eNone);
       
   387 		CActiveScheduler::Add(pStray);
       
   388 		pStray->Start1();
       
   389 		CActiveScheduler::Start();
       
   390 		}
       
   391 		break;
       
   392 	case EStraySignalNoSetActive:
       
   393 		{
       
   394 		CActiveScheduler::Install(pManager);
       
   395 		myStray* pStray = new myStray(eNone);
       
   396 		CActiveScheduler::Add(pStray);
       
   397 		pStray->Start2();
       
   398 		CActiveScheduler::Start();
       
   399 		}
       
   400 		break;
       
   401 	case ENormal:
       
   402 	default:
       
   403 		break;
       
   404 		}
       
   405 	delete pManager;
       
   406 	return(KPanicThreadRet);
       
   407 	}
       
   408 
       
   409 void myTimer::RunL()
       
   410 //
       
   411 // Handle the timer completion
       
   412 //
       
   413 	{
       
   414 
       
   415 	if (iIdentifier==KLeaveCode)	// Used to test that the request manager error() method is called
       
   416 		User::Leave(KmyErrorNum);
       
   417 	if (iIdentifier==KCancelCode) // Used to test cancelling an object
       
   418 		gTimer->Cancel();
       
   419 	order[iCount++]=iIdentifier;
       
   420 	if (iCount>=iNum)
       
   421 		CActiveScheduler::Stop();
       
   422 	}
       
   423 
       
   424 void myTimer::Start()
       
   425 //
       
   426 // Start a timer
       
   427 //
       
   428 	{
       
   429 
       
   430 	ConstructL();
       
   431 	CActiveScheduler::Add(this);
       
   432 	}
       
   433 
       
   434 void myThreadTimer::RunL()
       
   435 //
       
   436 // Handle timer completion
       
   437 //
       
   438 	{
       
   439 	
       
   440 	threadArray[iCount++]=iIdentifier;
       
   441 	if(iCount>=iNum)
       
   442 		CActiveScheduler::Stop();
       
   443 	}
       
   444 
       
   445 void myThreadTimer::Start()
       
   446 //
       
   447 // Start a timer
       
   448 //
       
   449 	{
       
   450 
       
   451 	ConstructL();
       
   452 	CActiveScheduler::Add(this);
       
   453 	}
       
   454 
       
   455 CreateStray::CreateStray(TInt aPriority)
       
   456 //
       
   457 // Constructor
       
   458 //
       
   459 	: CActive(aPriority)
       
   460 	{
       
   461 
       
   462 	iTimer.CreateLocal();
       
   463 	CActiveScheduler::Add(this);
       
   464 	iTimer.After(iStatus, 1000000);
       
   465 	}
       
   466 
       
   467 void TSecdulerTester::Test1()
       
   468 //
       
   469 // Test 1
       
   470 //
       
   471 	{
       
   472 
       
   473 //
       
   474 // Test the panics
       
   475 //
       
   476 
       
   477 	RThread thread;
       
   478 	TRequestStatus stat;
       
   479 //
       
   480 	test.Start(_L("First test normal thread termination"));
       
   481 	TInt r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ENormal);
       
   482 	test(r==KErrNone);
       
   483 	thread.Logon(stat);
       
   484 	thread.Resume();
       
   485 	User::WaitForRequest(stat);
       
   486 	test(thread.ExitCategory().Compare(_L("Kill"))==0);
       
   487 	test(thread.ExitReason()==KPanicThreadRet);	  
       
   488 	test(thread.ExitType()==EExitKill);
       
   489 	CLOSE_AND_WAIT(thread);
       
   490 //
       
   491 	test.Next(_L("Starting an uninstalled scheduler panics"));
       
   492 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStartUninstalled);
       
   493 	test(r==KErrNone);
       
   494 	thread.Logon(stat);
       
   495 	thread.Resume();
       
   496 	User::WaitForRequest(stat);
       
   497 	test(thread.ExitReason()==EReqManagerDoesNotExist);
       
   498 	test(thread.ExitType()==EExitPanic);
       
   499 	CLOSE_AND_WAIT(thread);
       
   500 //
       
   501 	test.Next(_L("Installing the scheduler twice panics"));
       
   502 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EInstallTwice);
       
   503 	test(r==KErrNone);
       
   504 	thread.Logon(stat);
       
   505 	thread.Resume();
       
   506 	User::WaitForRequest(stat);
       
   507 	test(thread.ExitReason()==EReqManagerAlreadyExists);
       
   508 	test(thread.ExitType()==EExitPanic);
       
   509 	CLOSE_AND_WAIT(thread);
       
   510 //
       
   511 	test.Next(_L("Stopping the scheduler twice panics"));
       
   512 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopTwice);
       
   513 	test(r==KErrNone);
       
   514 	thread.Logon(stat);
       
   515 	thread.Resume();
       
   516 	User::WaitForRequest(stat);
       
   517 	test(thread.ExitReason()==EReqTooManyStops);
       
   518 	test(thread.ExitType()==EExitPanic);
       
   519 	CLOSE_AND_WAIT(thread);
       
   520 //
       
   521 	test.Next(_L("Stopping an uninstalled scheduler panics"));
       
   522 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStopUninstalled);
       
   523 	test(r==KErrNone);
       
   524 	thread.Logon(stat);
       
   525 	thread.Resume();
       
   526 	User::WaitForRequest(stat);
       
   527 	test(thread.ExitReason()==EReqManagerDoesNotExist);
       
   528 	test(thread.ExitType()==EExitPanic);
       
   529 	CLOSE_AND_WAIT(thread);
       
   530 //
       
   531 	test.Next(_L("Setting an active object to active twice panics"));
       
   532 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ESetActiveTwice);
       
   533 	test(r==KErrNone);
       
   534 	thread.Logon(stat);
       
   535 	thread.Resume();
       
   536 	User::WaitForRequest(stat);
       
   537 	test(thread.ExitReason()==EReqAlreadyActive);
       
   538 	test(thread.ExitType()==EExitPanic);
       
   539 	CLOSE_AND_WAIT(thread);
       
   540 //
       
   541 	test.Next(_L("Adding an active object to an uninstalled scheduler panics"));
       
   542 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddToUninstalled);
       
   543 	test(r==KErrNone);
       
   544 	thread.Logon(stat);
       
   545 	thread.Resume();
       
   546 	User::WaitForRequest(stat);
       
   547 	test(thread.ExitReason()==EReqManagerDoesNotExist);
       
   548 	test(thread.ExitType()==EExitPanic);
       
   549 	CLOSE_AND_WAIT(thread);
       
   550 //
       
   551 	test.Next(_L("Adding NULL panics"));
       
   552 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddNull);
       
   553 	test(r==KErrNone);
       
   554 	thread.Logon(stat);
       
   555 	thread.Resume();
       
   556 	User::WaitForRequest(stat);
       
   557 	test(thread.ExitReason()==EReqNull);
       
   558 	test(thread.ExitType()==EExitPanic);
       
   559 	CLOSE_AND_WAIT(thread);
       
   560 //
       
   561 	test.Next(_L("Adding an active object twice panics"));
       
   562 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EAddTwice);
       
   563 	test(r==KErrNone);
       
   564 	thread.Logon(stat);
       
   565 	thread.Resume();
       
   566 	User::WaitForRequest(stat);
       
   567 	test(thread.ExitReason()==EReqAlreadyAdded);
       
   568 	test(thread.ExitType()==EExitPanic);
       
   569 	CLOSE_AND_WAIT(thread);
       
   570 //
       
   571 	test.Next(_L("A stray signal causes a panic"));
       
   572 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ECreateStray);
       
   573 	test(r==KErrNone);
       
   574 	thread.Logon(stat);
       
   575 	thread.Resume();
       
   576 	User::WaitForRequest(stat);
       
   577 	test(thread.ExitReason()==EReqStrayEvent);
       
   578 	test(thread.ExitType()==EExitPanic);
       
   579 	CLOSE_AND_WAIT(thread);
       
   580 //
       
   581 	test.Next(_L("Making a request on an unadded active object panics"));
       
   582 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)ERequestUnadded);
       
   583 	test(r==KErrNone);
       
   584 	thread.Logon(stat);
       
   585 	thread.Resume();
       
   586 	User::WaitForRequest(stat);
       
   587 	test(thread.ExitReason()==EActiveNotAdded);
       
   588 	test(thread.ExitType()==EExitPanic);
       
   589 	CLOSE_AND_WAIT(thread);
       
   590 //
       
   591 	test.Next(_L("The service provider does not set the status to KRequestPending"));
       
   592 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStraySignalNoKRequestPending);
       
   593 	test(r==KErrNone);
       
   594 	thread.Logon(stat);
       
   595 	thread.Resume();
       
   596 	User::WaitForRequest(stat);
       
   597 #ifdef _DEBUG
       
   598 	//this might fail if we're using a UREL euser
       
   599 	test(thread.ExitReason()==EReqStrayEvent);
       
   600 	test(thread.ExitType()==EExitPanic);
       
   601 #else
       
   602 	test(thread.ExitCategory().Compare(_L("Kill"))==0);
       
   603 	test(thread.ExitReason()==KPanicThreadRet);	  
       
   604 	test(thread.ExitType()==EExitKill);
       
   605 #endif 
       
   606 	CLOSE_AND_WAIT(thread);
       
   607 //
       
   608 #ifdef _DEBUG
       
   609 	//this might fail if we're using a UREL euser
       
   610 	test.Next(_L("The active object does not call SetActive"));
       
   611 	r=thread.Create(_L("myThread"),panicThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)EStraySignalNoSetActive);
       
   612 	test(r==KErrNone);
       
   613 	thread.Logon(stat);
       
   614 	thread.Resume();
       
   615 	User::WaitForRequest(stat);
       
   616 	test(thread.ExitReason()==EReqStrayEvent);
       
   617 	test(thread.ExitType()==EExitPanic);
       
   618 	CLOSE_AND_WAIT(thread);
       
   619 #endif
       
   620 //
       
   621 	test.End();
       
   622 	}
       
   623 
       
   624 void TSecdulerTester::Test2()
       
   625 //
       
   626 // Test 2
       
   627 //
       
   628 	{
       
   629 
       
   630 	test.Start(_L("Create timer"));
       
   631 	RTimer t;
       
   632 	TInt ret=t.CreateLocal();
       
   633 	test(ret==KErrNone);
       
   634 	TRequestStatus s;
       
   635 //
       
   636 	test.Next(_L("Test low is scheduled before lowest when timing equal"));
       
   637 	myTimer::SetNum(2);
       
   638 	pLowest->After(0);
       
   639 	pLow->After(0);
       
   640 	t.After(s, 100000);
       
   641 	test(s==KRequestPending);
       
   642 	User::WaitForRequest(s);
       
   643 	CActiveScheduler::Start();
       
   644 	test(order[0]==eLow && order[1]==eLowest);
       
   645 //
       
   646 	test.Next(_L("Test low is not before lowest when it expires later"));
       
   647 	myTimer::SetNum(2);
       
   648 	pLowest->After(0);
       
   649 	pLow->After(1000000);
       
   650 	CActiveScheduler::Start();
       
   651 	test(order[0]==eLowest && order[1]==eLow);
       
   652 //
       
   653 	test.Next(_L("Test none is scheduled before low"));
       
   654 	myTimer::SetNum(2);
       
   655 	pLow->After(0);
       
   656 	pNone->After(0);
       
   657 	t.After(s, 100000);
       
   658 	test(s==KRequestPending);
       
   659 	User::WaitForRequest(s);
       
   660 	CActiveScheduler::Start();
       
   661 	test(order[0]==eNone && order[1]==eLow);
       
   662 //
       
   663 	test.Next(_L("Test none is not before low when it expires later"));
       
   664 	myTimer::SetNum(2);
       
   665 	pLow->After(0);
       
   666 	pNone->After(1000000);
       
   667 	CActiveScheduler::Start();
       
   668 	test(order[0]==eLow && order[1]==eNone);
       
   669 //
       
   670 	test.Next(_L("Test high is scheduled before none"));
       
   671 	myTimer::SetNum(2);
       
   672 	pHigh->After(0);
       
   673 	pNone->After(0);
       
   674 	t.After(s, 100000);
       
   675 	test(s==KRequestPending);
       
   676 	User::WaitForRequest(s);
       
   677 	CActiveScheduler::Start();
       
   678 	test(order[0]==eHigh && order[1]==eNone);
       
   679 //
       
   680 	test.Next(_L("Test high is not before none when it expires later"));
       
   681 	myTimer::SetNum(2);
       
   682 	pHigh->After(1000000);
       
   683 	pNone->After(0);
       
   684 	CActiveScheduler::Start();
       
   685 	test(order[0]==eNone && order[1]==eHigh);
       
   686 //
       
   687 	test.Next(_L("Test highest is scheduled before high"));
       
   688 	myTimer::SetNum(2);
       
   689 	pHighest->After(0);
       
   690 	pHigh->After(0);
       
   691 	t.After(s, 100000);
       
   692 	test(s==KRequestPending);
       
   693 	User::WaitForRequest(s);
       
   694 	CActiveScheduler::Start();
       
   695 	test(order[0]==eHighest && order[1]==eHigh);
       
   696 //
       
   697 	test.Next(_L("Test highest is not before high when it expires later"));
       
   698 	myTimer::SetNum(2);
       
   699 	pHighest->After(1000000);
       
   700 	pHigh->After(0);
       
   701 	CActiveScheduler::Start();
       
   702 	test(order[0]==eHigh && order[1]==eHighest);
       
   703 //			  
       
   704 	test.Next(_L("Test all objects are scheduled in priority order"));
       
   705 	myTimer::SetNum(5);
       
   706 	pLowest->After(0);
       
   707 	pLow->After(0);
       
   708 	pNone->After(0);
       
   709 	pHigh->After(0);
       
   710 	pHighest->After(0);
       
   711 	t.After(s, 100000);
       
   712 	test(s==KRequestPending);
       
   713 	User::WaitForRequest(s);
       
   714 	CActiveScheduler::Start();
       
   715 	test(order[0]==eHighest && order[1]==eHigh && order[2]==eNone && order[3]==eLow && order[4]==eLowest);
       
   716 //
       
   717 	test.Next(_L("Test objects are scheduled according to expiry of timers"));
       
   718 	myTimer::SetNum(5);
       
   719 	pLowest->After(0);
       
   720 	pLow->After(500000);
       
   721 	pNone->After(1000000);
       
   722 	pHigh->After(1500000);
       
   723 	pHighest->After(2000000);
       
   724 	CActiveScheduler::Start();
       
   725 	test(order[4]==eHighest && order[3]==eHigh && order[2]==eNone && order[1]==eLow && order[0]==eLowest);
       
   726 //
       
   727 	test.Next(_L("Test with some objects having the same priority"));
       
   728 	myTimer::SetNum(7);
       
   729 	pLowest->After(0);
       
   730 	pLow->After(0);
       
   731 	pNone->After(0);
       
   732 	pHigh->After(0);
       
   733 	pHigh2->After(0);
       
   734 	pHigh3->After(0);
       
   735 	pHighest->After(0);	  
       
   736 	t.After(s, 100000);
       
   737 	test(s==KRequestPending);
       
   738 	User::WaitForRequest(s);
       
   739 	CActiveScheduler::Start();
       
   740 	test(order[0]==eHighest && order[1]==eHigh && order[2]==eHigh+2 && order[3]==eHigh+3 && order[4]==eNone && order[5]==eLow && order[6]==eLowest);
       
   741 //
       
   742 	test.End();
       
   743 	}
       
   744 
       
   745 void TSecdulerTester::Test3()
       
   746 //
       
   747 // Test 3
       
   748 //
       
   749 	{
       
   750 
       
   751 //
       
   752 // Test that a leave in a Run method calls the requestmanager error() method
       
   753 //
       
   754 	myTimer* pTimer=new myTimer(0, KLeaveCode);
       
   755 	pTimer->Start();
       
   756 	pTimer->After(100000);
       
   757 	TRAPD(ret,CActiveScheduler::Start());
       
   758 	test(ret==KmyErrorNum);		
       
   759 //
       
   760 // Test cancelling an object
       
   761 // Without the cancel the schedule order should be: pTimer1, gTimer, pTimer3
       
   762 // gTimer is cancelled so should not be scheduled 
       
   763 //
       
   764 	myTimer::SetNum(2);
       
   765 	myTimer* pTimer2=new myTimer(eHighest,KCancelCode);
       
   766 	myTimer* pTimer3=new myTimer(eLowest,eLowest);
       
   767 	pTimer2->Start();
       
   768 	pTimer2->After(100000);
       
   769 	gTimer->Start();
       
   770 	gTimer->After(1000000);
       
   771 	pTimer3->Start();
       
   772 	pTimer3->After(2000000);
       
   773 	CActiveScheduler::Start();
       
   774 	test(order[0]==KCancelCode && order[1]==eLowest);
       
   775 	delete pTimer;
       
   776 	delete pTimer2;
       
   777 	delete pTimer3;
       
   778 	}
       
   779 
       
   780 void TSecdulerTester::Test4()
       
   781 //
       
   782 // Create a thread with its own scheduler
       
   783 //
       
   784 	{	  
       
   785 
       
   786 	threadSemaphore.CreateLocal(0);
       
   787 	RThread myThread;
       
   788 	test(myThread.Create(_L("myThread"),myThreadEntryPoint,KDefaultStackSize,KHeapSize,KHeapSize,NULL)==KErrNone);
       
   789 	myThread.Resume();
       
   790 	myThread.Close();
       
   791 	Test2();
       
   792 	threadSemaphore.Wait();
       
   793 	User::After(100000);
       
   794 	}
       
   795 
       
   796 GLDEF_C TInt E32Main()
       
   797     {
       
   798 
       
   799 	// don't want just in time debugging as we trap panics
       
   800 	TBool justInTime=User::JustInTime(); 
       
   801 	User::SetJustInTime(EFalse); 
       
   802 
       
   803 	test.Title();
       
   804 	__UHEAP_MARK;
       
   805 //
       
   806 	test.Start(_L("Test1"));
       
   807 	TSecdulerTester sched;
       
   808 	sched.Test1();
       
   809 	MyManager* pManager=new MyManager;
       
   810 	test(pManager!=NULL);
       
   811 	CActiveScheduler::Install(pManager);
       
   812 	test(CActiveScheduler::Current()==pManager);
       
   813 	MyManager* pManager2=new MyManager;
       
   814 	test(pManager2!=NULL);
       
   815 	delete pManager2;
       
   816 	test(CActiveScheduler::Current()==pManager);
       
   817 	pLowest=new myTimer(eLowest,eLowest);
       
   818 	test(pLowest!=NULL);
       
   819 	pLow=new myTimer(eLow,eLow);
       
   820 	test(pLow!=NULL);
       
   821 	pNone=new myTimer(eNone,eNone);
       
   822 	test(pNone!=NULL);
       
   823 	pHigh=new myTimer(eHigh,eHigh);
       
   824 	test(pHigh!=NULL);
       
   825 	pHigh2=new myTimer(eHigh,eHigh+2);
       
   826 	test(pHigh2!=NULL);
       
   827 	pHigh3=new myTimer(eHigh,eHigh+3);
       
   828 	test(pHigh3!=NULL);
       
   829 	pHighest=new myTimer(eHighest,eHighest);
       
   830 	test(pHighest!=NULL);
       
   831 	pLowest->Start();
       
   832 	pLow->Start();
       
   833 	pNone->Start();
       
   834 	pHigh->Start();
       
   835 	pHigh2->Start();
       
   836 	pHigh3->Start();
       
   837 	pHighest->Start();
       
   838 //
       
   839 	test.Next(_L("Test2"));
       
   840 	sched.Test2();	
       
   841 	User::Check();
       
   842 //
       
   843 	test.Next(_L("Test3"));
       
   844 	gTimer=new myTimer(eNone, KgTimerID);
       
   845 	sched.Test3();
       
   846 //
       
   847 	test.Next(_L("Test4"));
       
   848 	sched.Test4();
       
   849 	delete gTimer;
       
   850 	User::Check();
       
   851 	delete pManager;
       
   852 	delete pLowest;
       
   853 	delete pLow;
       
   854 	delete pNone;
       
   855 	delete pHigh;
       
   856 	delete pHigh2;
       
   857 	delete pHigh3;
       
   858 	delete pHighest;
       
   859 //
       
   860 	test.End();
       
   861 	__UHEAP_MARKEND;
       
   862 
       
   863 	User::SetJustInTime(justInTime);
       
   864 	return(KErrNone);
       
   865     }