diff -r 000000000000 -r a41df078684a kerneltest/e32test/active/t_ctimer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/active/t_ctimer.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,327 @@ +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\active\t_ctimer.cpp +// Overview: +// Test timer functionality. +// API Information: +// CTimer +// Details: +// - Create some timer active objects, install an active scheduler, and the +// active objects, request event after an interval and verify that: +// - Absolute timer set with time less than current time return KErrUnderflow. +// - Relative timer set with 0 goes off immediately. +// - Absolute timer set to a time of now returns KErrUnderflow. +// - Absolute timer set with time more than the current time returns KErrNone. +// - Repeated timer is cancelled as expected. +// - Call relative timer's After function without adding it to the active scheduler +// and check for panic. +// - Call absolute timer's At function without adding it to the active scheduler and +// check for panic. +// - Check if heap has been corrupted by the tests. +// Platforms/Drives/Compatibility: +// All. +// Assumptions/Requirement/Pre-requisites: +// Failures and causes: +// Base Port information: +// +// + +#include +#include + +enum TDirective {ERelInvalidTime,ERelNotAdded,EAbNotAdded,EHighResNotAdded}; + +LOCAL_D RTest test(_L("T_CTIMER")); +LOCAL_D const TInt KRepeatID=999; +LOCAL_D const TInt ID1=101; +LOCAL_D const TInt ID2=102; +LOCAL_D const TInt ID3=103; +LOCAL_D TInt A[5]; //When a timer expires its identifier is placed in here + +class TestCTimer + { +public: + void Test1(); + void Test2(); + void Test3(); + }; + +class myScheduler : public CActiveScheduler + { +public: + virtual void Error(TInt anError)const{User::Leave(anError);} + }; + +class myTimer : public CTimer + { +public: + myTimer(const TInt aPriority, const TInt anId):CTimer(aPriority){iIdentifier=anId; iCount=0;} + void RunL(void); + void Start(void); + static void SetNum(const TInt aNum) {iNum=aNum; iTotalCount=0;} +private: + TInt iIdentifier; + TInt iCount; + static TInt iNum; + static TInt iTotalCount; + }; + +TInt myTimer::iTotalCount; +TInt myTimer::iNum; + +void myTimer::RunL(void) +// +// Timer has completed +// + { + + A[iTotalCount++]=iIdentifier; + if (iIdentifier==KRepeatID) + { + if(++iCount>2) + Cancel(); + else + After(100000); + } + if (iTotalCount>=iNum) + CActiveScheduler::Stop(); + } + +void myTimer::Start(void) +// +// Start a timer going. +// + { + + ConstructL(); + CActiveScheduler::Add(this); + } + +LOCAL_D TInt ThreadEntry(TAny* aDirective) +// +// Test thread +// + { + + myTimer* pTimer=new myTimer(0,ID1); + TTime time; + switch((TUint)aDirective) + { + case ERelInvalidTime: // Setting a relative timer with a negative time panics + CActiveScheduler::Install(new myScheduler); + pTimer->Start(); + pTimer->After(-100000); + break; + case ERelNotAdded: // Requesting an un-added relative timer panics + pTimer->After(100000); + break; + case EAbNotAdded: // Requesting an un-added absolute timer panics + time.HomeTime(); + pTimer->At(time); + break; + case EHighResNotAdded: // Requesting an un-added HighRes timer panics + pTimer->HighRes(100000); + break; + } + return(KErrNone); + } + +void TestCTimer::Test1() +// +// Test timer active objects. +// + { + + test.Start(_L("Create objects")); + myTimer* pTimer1=new myTimer(0, ID1); + myTimer* pTimer2=new myTimer(0, ID2); + myTimer* pTimer3=new myTimer(0, ID3); + TTime time; + pTimer1->Start(); + pTimer2->Start(); + pTimer3->Start(); +// + test.Next(_L("Abs timer with time less than now set KErrUnderflow")); + myTimer::SetNum(1); + time.HomeTime(); + pTimer1->At(time+TTimeIntervalSeconds(-1)); + CActiveScheduler::Start(); + test(pTimer1->iStatus==KErrUnderflow); +// + test.Next(_L("Rel timer with 0 goes off immediately")); + myTimer::SetNum(2); + pTimer1->After(0); + pTimer2->After(1000000); + CActiveScheduler::Start(); + test(A[0]==ID1 && A[1]==ID2); +// + test.Next(_L("Abs timer to a time of now sets KErrUnderflow")); + myTimer::SetNum(1); + time.UniversalTime(); + pTimer1->AtUTC(time); + CActiveScheduler::Start(); + test(pTimer1->iStatus==KErrUnderflow); +// + test.Next(_L("Abs timer set to future")); + myTimer::SetNum(2); + pTimer1->After(2000000); + time.HomeTime(); + pTimer2->At(time+TTimeIntervalSeconds(1)); + CActiveScheduler::Start(); + test(A[0]==ID2 && A[1]==ID1&& pTimer1->iStatus==KErrNone && pTimer2->iStatus==KErrNone); +// + test.Next(_L("Cancel a repeating timer after 3")); + myTimer::SetNum(4); + myTimer* pRepeater=new myTimer(0,KRepeatID); + pRepeater->Start(); + pTimer1->After(1000000); + pRepeater->After(100000); + CActiveScheduler::Start(); + test(A[0]==KRepeatID && A[1]==KRepeatID && A[2]==KRepeatID && A[3]==ID1); + +// + test.Next(_L("HighRes timer")); + myTimer::SetNum(1); + pTimer1->HighRes(1000000); + CActiveScheduler::Start(); + test(A[0]==ID1 && pTimer1->iStatus==KErrNone); +// + + test.Next(_L("Destroy objects")); + delete pTimer1; + delete pTimer2; + delete pTimer3; + delete pRepeater; +// + test.End(); + } + +void TestCTimer::Test2() +// +// Test the panics +// + { + + RThread thread; + TRequestStatus stat; +// +// Calling At or After or HighRes of an object not added to the queue panics +// + test.Start(_L("Queue rel when not added")); + test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)ERelNotAdded)==KErrNone); + thread.Logon(stat); + thread.Resume(); + User::WaitForRequest(stat); + test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0); + test(thread.ExitReason()==ETimNotAdded); + test(thread.ExitType()==EExitPanic); + CLOSE_AND_WAIT(thread); +// + test.Next(_L("Queue abs when not added")); + test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)EAbNotAdded)==KErrNone); + thread.Logon(stat); + thread.Resume(); + User::WaitForRequest(stat); + test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0); + test(thread.ExitReason()==ETimNotAdded); + test(thread.ExitType()==EExitPanic); + CLOSE_AND_WAIT(thread); +// + test.Next(_L("Queue HighRes when not added")); + test(thread.Create(_L("myThread"),ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)EHighResNotAdded)==KErrNone); + thread.Logon(stat); + thread.Resume(); + User::WaitForRequest(stat); + test(thread.ExitCategory().Compare(_L("E32USER-CBase"))==0); + test(thread.ExitReason()==ETimNotAdded); + test(thread.ExitType()==EExitPanic); + CLOSE_AND_WAIT(thread); +// + test.End(); + } + +LOCAL_D TInt Test3ThreadEntry(TAny* aArg) +// +// Test thread for RTimer::HighRes +// + { + TRequestStatus status; + RTimer timer; + TInt r = timer.CreateLocal(); + if (r != KErrNone) + return r; + timer.HighRes(status, (TInt) aArg); + timer.Cancel(); + User::WaitForRequest(status); + timer.Close(); + if (status != KErrNone && status != KErrCancel) + return status.Int(); + return KErrNone; + } + +void TestRTimerHighRes(TInt aInterval, TExitType aExpectedExitType) + { + RThread thread; + TRequestStatus stat; + test(thread.Create(_L("myThread"),Test3ThreadEntry,KDefaultStackSize,0x2000,0x2000,(TAny*)aInterval)==KErrNone); + thread.Logon(stat); + thread.Resume(); + User::WaitForRequest(stat); + test(thread.ExitType()==aExpectedExitType); + if (thread.ExitType()==EExitKill) + test(thread.ExitReason()==KErrNone); + CLOSE_AND_WAIT(thread); + } + +void TestCTimer::Test3() +// +// Test RTimer::HighRes argument checking +// + { + test.Start(_L("Test RTimer::HighRes argument checking")); + TestRTimerHighRes(0, EExitKill); + TestRTimerHighRes(0x7FFFEC79, EExitKill); + TestRTimerHighRes(0x7FFFFFFF, EExitKill); + TestRTimerHighRes(0x80000000, EExitPanic); + test.End(); + } + +GLDEF_C TInt E32Main() +// +// Test the CTimer class +// + { + // don't want just in time debugging as we trap panics + TBool justInTime=User::JustInTime(); + User::SetJustInTime(EFalse); + + test.Title(); + __UHEAP_MARK; + TestCTimer T; + myScheduler* pScheduler=new myScheduler; + CActiveScheduler::Install(pScheduler); + test.Start(_L("Test1")); + T.Test1(); + test.Next(_L("Test2")); + T.Test2(); + CActiveScheduler::Install(NULL); + delete pScheduler; + T.Test3(); + test.End(); + __UHEAP_MARKEND; + + User::SetJustInTime(justInTime); + return(KErrNone); + } +