kerneltest/e32test/active/t_ctimer.cpp
changeset 0 a41df078684a
child 231 75252ea6123b
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_ctimer.cpp
       
    15 // Overview:
       
    16 // Test timer functionality.
       
    17 // API Information:
       
    18 // CTimer 
       
    19 // Details:
       
    20 // - Create some timer active objects, install an active scheduler, and the
       
    21 // active objects, request event after an interval and verify that:
       
    22 // - Absolute timer set with time less than current time return KErrUnderflow.
       
    23 // - Relative timer set with 0 goes off immediately.
       
    24 // - Absolute timer set to a time of now returns KErrUnderflow.
       
    25 // - Absolute timer set with time more than the current time returns KErrNone.
       
    26 // - Repeated timer is cancelled as expected.
       
    27 // - Call relative timer's After function without adding it to the active scheduler 
       
    28 // and check for panic.
       
    29 // - Call absolute timer's At function without adding it to the active scheduler and 
       
    30 // check for panic.
       
    31 // - Check if heap has been corrupted by the tests.
       
    32 // Platforms/Drives/Compatibility:
       
    33 // All.
       
    34 // Assumptions/Requirement/Pre-requisites:
       
    35 // Failures and causes:
       
    36 // Base Port information:
       
    37 // 
       
    38 //
       
    39 
       
    40 #include <e32test.h>
       
    41 #include <e32panic.h>
       
    42 
       
    43 enum TDirective {ERelInvalidTime,ERelNotAdded,EAbNotAdded,EHighResNotAdded};
       
    44 
       
    45 LOCAL_D RTest test(_L("T_CTIMER"));
       
    46 LOCAL_D const TInt KRepeatID=999; 	
       
    47 LOCAL_D const TInt ID1=101;
       
    48 LOCAL_D const TInt ID2=102;
       
    49 LOCAL_D const TInt ID3=103;
       
    50 LOCAL_D TInt A[5]; //When a timer expires its identifier is placed in here
       
    51 
       
    52 class TestCTimer
       
    53 	{
       
    54 public:
       
    55 	void Test1();
       
    56 	void Test2();
       
    57 	void Test3();
       
    58 	};
       
    59 
       
    60 class myScheduler : public CActiveScheduler
       
    61 	{
       
    62 public:
       
    63 	virtual void Error(TInt anError)const{User::Leave(anError);}
       
    64 	};
       
    65 
       
    66 class myTimer : public CTimer
       
    67 	{
       
    68 public:
       
    69 	myTimer(const TInt aPriority, const TInt anId):CTimer(aPriority){iIdentifier=anId; iCount=0;}
       
    70 	void RunL(void);	
       
    71 	void Start(void);
       
    72 	static void SetNum(const TInt aNum) {iNum=aNum; iTotalCount=0;}
       
    73 private:
       
    74 	TInt iIdentifier;
       
    75 	TInt iCount;
       
    76 	static TInt iNum;
       
    77 	static TInt iTotalCount;
       
    78 	};
       
    79 
       
    80 TInt myTimer::iTotalCount;
       
    81 TInt myTimer::iNum;
       
    82 
       
    83 void myTimer::RunL(void)
       
    84 //
       
    85 // Timer has completed
       
    86 //
       
    87 	{
       
    88 
       
    89 	A[iTotalCount++]=iIdentifier;
       
    90 	if (iIdentifier==KRepeatID)
       
    91 		{
       
    92 		if(++iCount>2)
       
    93 			Cancel();
       
    94 		else
       
    95 			After(100000);
       
    96 		}
       
    97 	if (iTotalCount>=iNum)
       
    98 		CActiveScheduler::Stop();
       
    99 	}
       
   100 
       
   101 void myTimer::Start(void)
       
   102 //
       
   103 // Start a timer going.
       
   104 //
       
   105 	{
       
   106 
       
   107 	ConstructL();
       
   108 	CActiveScheduler::Add(this);
       
   109 	}
       
   110 
       
   111 LOCAL_D TInt ThreadEntry(TAny* aDirective)
       
   112 //
       
   113 // Test thread
       
   114 //
       
   115 	{
       
   116 
       
   117 	myTimer* pTimer=new myTimer(0,ID1);
       
   118 	TTime time;
       
   119 	switch((TUint)aDirective)
       
   120 		{
       
   121 	case ERelInvalidTime: // Setting a relative timer with a negative time panics 
       
   122 		CActiveScheduler::Install(new myScheduler);
       
   123 		pTimer->Start();
       
   124 		pTimer->After(-100000); 
       
   125 		break;	
       
   126 	case ERelNotAdded: 	// Requesting an un-added relative timer panics
       
   127 		pTimer->After(100000);
       
   128 		break; 	
       
   129 	case EAbNotAdded: // Requesting an un-added absolute timer panics
       
   130 		time.HomeTime(); 
       
   131 		pTimer->At(time); 
       
   132 		break;
       
   133 	case EHighResNotAdded: // Requesting an un-added HighRes timer panics
       
   134 		pTimer->HighRes(100000);
       
   135 		break;
       
   136 		}
       
   137 	return(KErrNone);
       
   138 	}
       
   139 
       
   140 void TestCTimer::Test1()
       
   141 //
       
   142 // Test timer active objects.
       
   143 //
       
   144 	{
       
   145 
       
   146 	test.Start(_L("Create objects"));
       
   147 	myTimer* pTimer1=new myTimer(0, ID1);
       
   148 	myTimer* pTimer2=new myTimer(0, ID2);
       
   149 	myTimer* pTimer3=new myTimer(0, ID3);
       
   150 	TTime time;
       
   151 	pTimer1->Start();
       
   152 	pTimer2->Start();
       
   153 	pTimer3->Start();
       
   154 //
       
   155 	test.Next(_L("Abs timer with time less than now set KErrUnderflow"));
       
   156 	myTimer::SetNum(1);
       
   157 	time.HomeTime();
       
   158 	pTimer1->At(time+TTimeIntervalSeconds(-1));
       
   159 	CActiveScheduler::Start();
       
   160 	test(pTimer1->iStatus==KErrUnderflow);
       
   161 //
       
   162 	test.Next(_L("Rel timer with 0 goes off immediately"));
       
   163 	myTimer::SetNum(2);
       
   164 	pTimer1->After(0);
       
   165 	pTimer2->After(1000000);
       
   166 	CActiveScheduler::Start();
       
   167 	test(A[0]==ID1 && A[1]==ID2);
       
   168 //
       
   169 	test.Next(_L("Abs timer to a time of now sets KErrUnderflow"));
       
   170 	myTimer::SetNum(1);
       
   171 	time.UniversalTime();
       
   172 	pTimer1->AtUTC(time);
       
   173 	CActiveScheduler::Start();
       
   174 	test(pTimer1->iStatus==KErrUnderflow);
       
   175 //
       
   176 	test.Next(_L("Abs timer set to future"));
       
   177 	myTimer::SetNum(2);
       
   178 	pTimer1->After(2000000);
       
   179 	time.HomeTime();
       
   180 	pTimer2->At(time+TTimeIntervalSeconds(1));
       
   181 	CActiveScheduler::Start();
       
   182 	test(A[0]==ID2 && A[1]==ID1&& pTimer1->iStatus==KErrNone && pTimer2->iStatus==KErrNone);
       
   183 //  
       
   184   	test.Next(_L("Cancel a repeating timer after 3"));
       
   185 	myTimer::SetNum(4);
       
   186 	myTimer* pRepeater=new myTimer(0,KRepeatID);
       
   187 	pRepeater->Start();
       
   188 	pTimer1->After(1000000);
       
   189 	pRepeater->After(100000);
       
   190 	CActiveScheduler::Start();
       
   191 	test(A[0]==KRepeatID && A[1]==KRepeatID && A[2]==KRepeatID && A[3]==ID1);
       
   192 
       
   193 //
       
   194 	test.Next(_L("HighRes timer"));
       
   195 	myTimer::SetNum(1);
       
   196 	pTimer1->HighRes(1000000);
       
   197 	CActiveScheduler::Start();
       
   198 	test(A[0]==ID1 && pTimer1->iStatus==KErrNone);
       
   199 //
       
   200 
       
   201 	test.Next(_L("Destroy objects"));
       
   202 	delete pTimer1;
       
   203 	delete pTimer2;
       
   204 	delete pTimer3;
       
   205 	delete pRepeater;
       
   206 //
       
   207 	test.End();
       
   208 	}
       
   209 
       
   210 void TestCTimer::Test2()
       
   211 //
       
   212 // Test the panics
       
   213 //
       
   214 	{
       
   215 
       
   216 	RThread thread;
       
   217 	TRequestStatus stat;
       
   218 //
       
   219 // Calling At or After or HighRes of an object not added to the queue panics
       
   220 //
       
   221 	test.Start(_L("Queue rel when not added"));
       
   222 	test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)ERelNotAdded)==KErrNone);
       
   223 	thread.Logon(stat);
       
   224 	thread.Resume();
       
   225 	User::WaitForRequest(stat);
       
   226 	test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0);
       
   227 	test(thread.ExitReason()==ETimNotAdded);				
       
   228 	test(thread.ExitType()==EExitPanic);				   
       
   229 	CLOSE_AND_WAIT(thread);
       
   230 //
       
   231 	test.Next(_L("Queue abs when not added"));
       
   232 	test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)EAbNotAdded)==KErrNone);
       
   233 	thread.Logon(stat);
       
   234 	thread.Resume();
       
   235 	User::WaitForRequest(stat);
       
   236 	test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0);
       
   237 	test(thread.ExitReason()==ETimNotAdded);				
       
   238 	test(thread.ExitType()==EExitPanic);				   	
       
   239 	CLOSE_AND_WAIT(thread);
       
   240 //
       
   241 	test.Next(_L("Queue HighRes when not added"));
       
   242 	test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)EHighResNotAdded)==KErrNone);
       
   243 	thread.Logon(stat);
       
   244 	thread.Resume();
       
   245 	User::WaitForRequest(stat);
       
   246 	test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0);
       
   247 	test(thread.ExitReason()==ETimNotAdded);				
       
   248 	test(thread.ExitType()==EExitPanic);				   	
       
   249 	CLOSE_AND_WAIT(thread);
       
   250 //
       
   251 	test.End();
       
   252 	}
       
   253 
       
   254 LOCAL_D TInt Test3ThreadEntry(TAny* aArg)
       
   255 //
       
   256 // Test thread for RTimer::HighRes
       
   257 //
       
   258 	{
       
   259 	TRequestStatus status;
       
   260 	RTimer timer;
       
   261 	TInt r = timer.CreateLocal();
       
   262 	if (r != KErrNone)
       
   263 		return r;
       
   264 	timer.HighRes(status, (TInt) aArg);
       
   265 	timer.Cancel();
       
   266 	User::WaitForRequest(status);
       
   267 	timer.Close();
       
   268 	if (status != KErrNone && status != KErrCancel)
       
   269 		return status.Int();	
       
   270 	return KErrNone;
       
   271 	}
       
   272 
       
   273 void TestRTimerHighRes(TInt aInterval, TExitType aExpectedExitType)
       
   274 	{
       
   275 	RThread thread;
       
   276 	TRequestStatus stat;
       
   277 	test(thread.Create(_L("myThread"),Test3ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)aInterval)==KErrNone);
       
   278 	thread.Logon(stat);
       
   279 	thread.Resume();
       
   280 	User::WaitForRequest(stat);
       
   281 	test(thread.ExitType()==aExpectedExitType);
       
   282 	if (thread.ExitType()==EExitKill)
       
   283 		test(thread.ExitReason()==KErrNone);
       
   284 	CLOSE_AND_WAIT(thread);
       
   285 	}
       
   286 
       
   287 void TestCTimer::Test3()
       
   288 //
       
   289 // Test RTimer::HighRes argument checking
       
   290 //
       
   291 	{
       
   292 	test.Start(_L("Test RTimer::HighRes argument checking"));
       
   293 	TestRTimerHighRes(0, EExitKill);
       
   294 	TestRTimerHighRes(0x7FFFEC79, EExitKill);
       
   295 	TestRTimerHighRes(0x7FFFFFFF, EExitKill);
       
   296 	TestRTimerHighRes(0x80000000, EExitPanic);
       
   297 	test.End();
       
   298 	}
       
   299 
       
   300 GLDEF_C TInt E32Main()
       
   301 //
       
   302 // Test the CTimer class
       
   303 //
       
   304     {
       
   305 	// don't want just in time debugging as we trap panics
       
   306 	TBool justInTime=User::JustInTime(); 
       
   307 	User::SetJustInTime(EFalse); 
       
   308 
       
   309 	test.Title();
       
   310 	__UHEAP_MARK;
       
   311 	TestCTimer T;
       
   312 	myScheduler* pScheduler=new myScheduler;
       
   313 	CActiveScheduler::Install(pScheduler);
       
   314 	test.Start(_L("Test1"));
       
   315 	T.Test1();
       
   316 	test.Next(_L("Test2"));
       
   317 	T.Test2();
       
   318 	CActiveScheduler::Install(NULL);
       
   319 	delete pScheduler;
       
   320 	T.Test3();
       
   321 	test.End();
       
   322 	__UHEAP_MARKEND;
       
   323 
       
   324 	User::SetJustInTime(justInTime);
       
   325 	return(KErrNone);
       
   326     }
       
   327