os/kernelhwsrv/kerneltest/e32test/active/t_ctimer.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/active/t_ctimer.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,327 @@
     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_ctimer.cpp
    1.18 +// Overview:
    1.19 +// Test timer functionality.
    1.20 +// API Information:
    1.21 +// CTimer 
    1.22 +// Details:
    1.23 +// - Create some timer active objects, install an active scheduler, and the
    1.24 +// active objects, request event after an interval and verify that:
    1.25 +// - Absolute timer set with time less than current time return KErrUnderflow.
    1.26 +// - Relative timer set with 0 goes off immediately.
    1.27 +// - Absolute timer set to a time of now returns KErrUnderflow.
    1.28 +// - Absolute timer set with time more than the current time returns KErrNone.
    1.29 +// - Repeated timer is cancelled as expected.
    1.30 +// - Call relative timer's After function without adding it to the active scheduler 
    1.31 +// and check for panic.
    1.32 +// - Call absolute timer's At function without adding it to the active scheduler and 
    1.33 +// check for panic.
    1.34 +// - Check if heap has been corrupted by the tests.
    1.35 +// Platforms/Drives/Compatibility:
    1.36 +// All.
    1.37 +// Assumptions/Requirement/Pre-requisites:
    1.38 +// Failures and causes:
    1.39 +// Base Port information:
    1.40 +// 
    1.41 +//
    1.42 +
    1.43 +#include <e32test.h>
    1.44 +#include <e32panic.h>
    1.45 +
    1.46 +enum TDirective {ERelInvalidTime,ERelNotAdded,EAbNotAdded,EHighResNotAdded};
    1.47 +
    1.48 +LOCAL_D RTest test(_L("T_CTIMER"));
    1.49 +LOCAL_D const TInt KRepeatID=999; 	
    1.50 +LOCAL_D const TInt ID1=101;
    1.51 +LOCAL_D const TInt ID2=102;
    1.52 +LOCAL_D const TInt ID3=103;
    1.53 +LOCAL_D TInt A[5]; //When a timer expires its identifier is placed in here
    1.54 +
    1.55 +class TestCTimer
    1.56 +	{
    1.57 +public:
    1.58 +	void Test1();
    1.59 +	void Test2();
    1.60 +	void Test3();
    1.61 +	};
    1.62 +
    1.63 +class myScheduler : public CActiveScheduler
    1.64 +	{
    1.65 +public:
    1.66 +	virtual void Error(TInt anError)const{User::Leave(anError);}
    1.67 +	};
    1.68 +
    1.69 +class myTimer : public CTimer
    1.70 +	{
    1.71 +public:
    1.72 +	myTimer(const TInt aPriority, const TInt anId):CTimer(aPriority){iIdentifier=anId; iCount=0;}
    1.73 +	void RunL(void);	
    1.74 +	void Start(void);
    1.75 +	static void SetNum(const TInt aNum) {iNum=aNum; iTotalCount=0;}
    1.76 +private:
    1.77 +	TInt iIdentifier;
    1.78 +	TInt iCount;
    1.79 +	static TInt iNum;
    1.80 +	static TInt iTotalCount;
    1.81 +	};
    1.82 +
    1.83 +TInt myTimer::iTotalCount;
    1.84 +TInt myTimer::iNum;
    1.85 +
    1.86 +void myTimer::RunL(void)
    1.87 +//
    1.88 +// Timer has completed
    1.89 +//
    1.90 +	{
    1.91 +
    1.92 +	A[iTotalCount++]=iIdentifier;
    1.93 +	if (iIdentifier==KRepeatID)
    1.94 +		{
    1.95 +		if(++iCount>2)
    1.96 +			Cancel();
    1.97 +		else
    1.98 +			After(100000);
    1.99 +		}
   1.100 +	if (iTotalCount>=iNum)
   1.101 +		CActiveScheduler::Stop();
   1.102 +	}
   1.103 +
   1.104 +void myTimer::Start(void)
   1.105 +//
   1.106 +// Start a timer going.
   1.107 +//
   1.108 +	{
   1.109 +
   1.110 +	ConstructL();
   1.111 +	CActiveScheduler::Add(this);
   1.112 +	}
   1.113 +
   1.114 +LOCAL_D TInt ThreadEntry(TAny* aDirective)
   1.115 +//
   1.116 +// Test thread
   1.117 +//
   1.118 +	{
   1.119 +
   1.120 +	myTimer* pTimer=new myTimer(0,ID1);
   1.121 +	TTime time;
   1.122 +	switch((TUint)aDirective)
   1.123 +		{
   1.124 +	case ERelInvalidTime: // Setting a relative timer with a negative time panics 
   1.125 +		CActiveScheduler::Install(new myScheduler);
   1.126 +		pTimer->Start();
   1.127 +		pTimer->After(-100000); 
   1.128 +		break;	
   1.129 +	case ERelNotAdded: 	// Requesting an un-added relative timer panics
   1.130 +		pTimer->After(100000);
   1.131 +		break; 	
   1.132 +	case EAbNotAdded: // Requesting an un-added absolute timer panics
   1.133 +		time.HomeTime(); 
   1.134 +		pTimer->At(time); 
   1.135 +		break;
   1.136 +	case EHighResNotAdded: // Requesting an un-added HighRes timer panics
   1.137 +		pTimer->HighRes(100000);
   1.138 +		break;
   1.139 +		}
   1.140 +	return(KErrNone);
   1.141 +	}
   1.142 +
   1.143 +void TestCTimer::Test1()
   1.144 +//
   1.145 +// Test timer active objects.
   1.146 +//
   1.147 +	{
   1.148 +
   1.149 +	test.Start(_L("Create objects"));
   1.150 +	myTimer* pTimer1=new myTimer(0, ID1);
   1.151 +	myTimer* pTimer2=new myTimer(0, ID2);
   1.152 +	myTimer* pTimer3=new myTimer(0, ID3);
   1.153 +	TTime time;
   1.154 +	pTimer1->Start();
   1.155 +	pTimer2->Start();
   1.156 +	pTimer3->Start();
   1.157 +//
   1.158 +	test.Next(_L("Abs timer with time less than now set KErrUnderflow"));
   1.159 +	myTimer::SetNum(1);
   1.160 +	time.HomeTime();
   1.161 +	pTimer1->At(time+TTimeIntervalSeconds(-1));
   1.162 +	CActiveScheduler::Start();
   1.163 +	test(pTimer1->iStatus==KErrUnderflow);
   1.164 +//
   1.165 +	test.Next(_L("Rel timer with 0 goes off immediately"));
   1.166 +	myTimer::SetNum(2);
   1.167 +	pTimer1->After(0);
   1.168 +	pTimer2->After(1000000);
   1.169 +	CActiveScheduler::Start();
   1.170 +	test(A[0]==ID1 && A[1]==ID2);
   1.171 +//
   1.172 +	test.Next(_L("Abs timer to a time of now sets KErrUnderflow"));
   1.173 +	myTimer::SetNum(1);
   1.174 +	time.UniversalTime();
   1.175 +	pTimer1->AtUTC(time);
   1.176 +	CActiveScheduler::Start();
   1.177 +	test(pTimer1->iStatus==KErrUnderflow);
   1.178 +//
   1.179 +	test.Next(_L("Abs timer set to future"));
   1.180 +	myTimer::SetNum(2);
   1.181 +	pTimer1->After(2000000);
   1.182 +	time.HomeTime();
   1.183 +	pTimer2->At(time+TTimeIntervalSeconds(1));
   1.184 +	CActiveScheduler::Start();
   1.185 +	test(A[0]==ID2 && A[1]==ID1&& pTimer1->iStatus==KErrNone && pTimer2->iStatus==KErrNone);
   1.186 +//  
   1.187 +  	test.Next(_L("Cancel a repeating timer after 3"));
   1.188 +	myTimer::SetNum(4);
   1.189 +	myTimer* pRepeater=new myTimer(0,KRepeatID);
   1.190 +	pRepeater->Start();
   1.191 +	pTimer1->After(1000000);
   1.192 +	pRepeater->After(100000);
   1.193 +	CActiveScheduler::Start();
   1.194 +	test(A[0]==KRepeatID && A[1]==KRepeatID && A[2]==KRepeatID && A[3]==ID1);
   1.195 +
   1.196 +//
   1.197 +	test.Next(_L("HighRes timer"));
   1.198 +	myTimer::SetNum(1);
   1.199 +	pTimer1->HighRes(1000000);
   1.200 +	CActiveScheduler::Start();
   1.201 +	test(A[0]==ID1 && pTimer1->iStatus==KErrNone);
   1.202 +//
   1.203 +
   1.204 +	test.Next(_L("Destroy objects"));
   1.205 +	delete pTimer1;
   1.206 +	delete pTimer2;
   1.207 +	delete pTimer3;
   1.208 +	delete pRepeater;
   1.209 +//
   1.210 +	test.End();
   1.211 +	}
   1.212 +
   1.213 +void TestCTimer::Test2()
   1.214 +//
   1.215 +// Test the panics
   1.216 +//
   1.217 +	{
   1.218 +
   1.219 +	RThread thread;
   1.220 +	TRequestStatus stat;
   1.221 +//
   1.222 +// Calling At or After or HighRes of an object not added to the queue panics
   1.223 +//
   1.224 +	test.Start(_L("Queue rel when not added"));
   1.225 +	test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)ERelNotAdded)==KErrNone);
   1.226 +	thread.Logon(stat);
   1.227 +	thread.Resume();
   1.228 +	User::WaitForRequest(stat);
   1.229 +	test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0);
   1.230 +	test(thread.ExitReason()==ETimNotAdded);				
   1.231 +	test(thread.ExitType()==EExitPanic);				   
   1.232 +	CLOSE_AND_WAIT(thread);
   1.233 +//
   1.234 +	test.Next(_L("Queue abs when not added"));
   1.235 +	test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)EAbNotAdded)==KErrNone);
   1.236 +	thread.Logon(stat);
   1.237 +	thread.Resume();
   1.238 +	User::WaitForRequest(stat);
   1.239 +	test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0);
   1.240 +	test(thread.ExitReason()==ETimNotAdded);				
   1.241 +	test(thread.ExitType()==EExitPanic);				   	
   1.242 +	CLOSE_AND_WAIT(thread);
   1.243 +//
   1.244 +	test.Next(_L("Queue HighRes when not added"));
   1.245 +	test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)EHighResNotAdded)==KErrNone);
   1.246 +	thread.Logon(stat);
   1.247 +	thread.Resume();
   1.248 +	User::WaitForRequest(stat);
   1.249 +	test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0);
   1.250 +	test(thread.ExitReason()==ETimNotAdded);				
   1.251 +	test(thread.ExitType()==EExitPanic);				   	
   1.252 +	CLOSE_AND_WAIT(thread);
   1.253 +//
   1.254 +	test.End();
   1.255 +	}
   1.256 +
   1.257 +LOCAL_D TInt Test3ThreadEntry(TAny* aArg)
   1.258 +//
   1.259 +// Test thread for RTimer::HighRes
   1.260 +//
   1.261 +	{
   1.262 +	TRequestStatus status;
   1.263 +	RTimer timer;
   1.264 +	TInt r = timer.CreateLocal();
   1.265 +	if (r != KErrNone)
   1.266 +		return r;
   1.267 +	timer.HighRes(status, (TInt) aArg);
   1.268 +	timer.Cancel();
   1.269 +	User::WaitForRequest(status);
   1.270 +	timer.Close();
   1.271 +	if (status != KErrNone && status != KErrCancel)
   1.272 +		return status.Int();	
   1.273 +	return KErrNone;
   1.274 +	}
   1.275 +
   1.276 +void TestRTimerHighRes(TInt aInterval, TExitType aExpectedExitType)
   1.277 +	{
   1.278 +	RThread thread;
   1.279 +	TRequestStatus stat;
   1.280 +	test(thread.Create(_L("myThread"),Test3ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)aInterval)==KErrNone);
   1.281 +	thread.Logon(stat);
   1.282 +	thread.Resume();
   1.283 +	User::WaitForRequest(stat);
   1.284 +	test(thread.ExitType()==aExpectedExitType);
   1.285 +	if (thread.ExitType()==EExitKill)
   1.286 +		test(thread.ExitReason()==KErrNone);
   1.287 +	CLOSE_AND_WAIT(thread);
   1.288 +	}
   1.289 +
   1.290 +void TestCTimer::Test3()
   1.291 +//
   1.292 +// Test RTimer::HighRes argument checking
   1.293 +//
   1.294 +	{
   1.295 +	test.Start(_L("Test RTimer::HighRes argument checking"));
   1.296 +	TestRTimerHighRes(0, EExitKill);
   1.297 +	TestRTimerHighRes(0x7FFFEC79, EExitKill);
   1.298 +	TestRTimerHighRes(0x7FFFFFFF, EExitKill);
   1.299 +	TestRTimerHighRes(0x80000000, EExitPanic);
   1.300 +	test.End();
   1.301 +	}
   1.302 +
   1.303 +GLDEF_C TInt E32Main()
   1.304 +//
   1.305 +// Test the CTimer class
   1.306 +//
   1.307 +    {
   1.308 +	// don't want just in time debugging as we trap panics
   1.309 +	TBool justInTime=User::JustInTime(); 
   1.310 +	User::SetJustInTime(EFalse); 
   1.311 +
   1.312 +	test.Title();
   1.313 +	__UHEAP_MARK;
   1.314 +	TestCTimer T;
   1.315 +	myScheduler* pScheduler=new myScheduler;
   1.316 +	CActiveScheduler::Install(pScheduler);
   1.317 +	test.Start(_L("Test1"));
   1.318 +	T.Test1();
   1.319 +	test.Next(_L("Test2"));
   1.320 +	T.Test2();
   1.321 +	CActiveScheduler::Install(NULL);
   1.322 +	delete pScheduler;
   1.323 +	T.Test3();
   1.324 +	test.End();
   1.325 +	__UHEAP_MARKEND;
   1.326 +
   1.327 +	User::SetJustInTime(justInTime);
   1.328 +	return(KErrNone);
   1.329 +    }
   1.330 +