--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/keepalive/flextimer/test/testflextimer/src/testflexperiodic.cpp Mon May 24 20:51:35 2010 +0300
@@ -0,0 +1,2091 @@
+/*
+* ============================================================================
+* Name : testflexperiodic.cpp
+* Part of : src / testflextimer
+* Description : STIF test cases for CFlexPeriodic timer.
+* Version : %version: 1 %
+*
+* Copyright © 2010 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:
+* Nokia Corporation
+* ============================================================================
+* Template version: 4.1
+*/
+
+#include <e32debug.h> // for RDebug
+#include <flexperiodic.h> // for CFlexPeriodic
+#include <stiftesteventinterface.h> // for TEventIf
+#include "testflextimer.h" // for global constants
+#include "testflexperiodic.h"
+
+/**
+ * Timer can be expired 1 sec late
+ *
+ * Note! Definition
+ *
+ * const TTimeIntervalMicroSeconds32 KTimerResolution( 1000000 );
+ *
+ * will cause writable static data due non-trivial constructor of
+ * TTimeIntervalMicroSeconds32.
+ *
+ */
+const TInt KTimerResolution( 1000000 );
+
+// ======== LOCAL FUNCTIONS ========
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------------
+//
+CTestFlexPeriodic::CTestFlexPeriodic()
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CTestFlexPeriodic::~CTestFlexPeriodic()
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// _ _ _ ____ _ ___ _ ____ ____ ___
+// | | | |__| | | | | | | | |__]
+// |_|_| | | | | |___ |__| |__| |
+//
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// Start scheduler for given time.
+// ---------------------------------------------------------------------------
+//
+void CTestFlexPeriodic::WaitL( TTimeIntervalMicroSeconds32 aPeriod )
+ {
+ CPeriodic* watchdog = CPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( watchdog );
+ watchdog->Start( aPeriod, aPeriod, TCallBack( StopScheduler, NULL ) );
+
+ // Start scheduler. Wait here until the timer expires and stops the
+ // scheduler.
+ CActiveScheduler::Start();
+
+ // Clean-up
+ watchdog->Cancel();
+ CleanupStack::PopAndDestroy( watchdog );
+ }
+
+// ---------------------------------------------------------------------------
+// TCallBack function to stop the scheduler.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StopScheduler( TAny* /* aArgument */ )
+ {
+ CActiveScheduler::Stop();
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// ____ ____ _ _ ___ ____ ____ _ _ ____
+// | |__| | | |__] |__| | |_/ [__
+// |___ | | |___ |___ |__] | | |___ | \_ ___]
+//
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// TCallBack function that does nothing. Not ment to be called - just to
+// fulfill the interface.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::DoNothing( TAny* /* aArgument */ )
+ {
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TCallBack function that panics testcase if it get called.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::PanicClient( TAny* /* aArgument */ )
+ {
+ User::Panic(_L("NotCalled CB got called"), 0xDEAD);
+ return KErrNone;
+ }
+// ---------------------------------------------------------------------------
+// TCallBack function for adding time stamp to an RArray of TTimes.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::AddTimestamp( TAny* aArgument )
+ {
+ __ASSERT_ALWAYS(
+ aArgument != NULL,
+ User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
+
+ //RDebug::Print( _L("CTestFlexPeriodic::AddTimestamp()") );
+
+ RArray<TTime>* times = reinterpret_cast<RArray<TTime>*>( aArgument );
+
+ TTime now;
+ now.UniversalTime();
+
+ TInt err = times->Append( now ); // Data is copied by RArray
+ __ASSERT_ALWAYS(
+ err == KErrNone,
+ User::Panic( KTestFlexTimerPanicCategory, err ) );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TCallBack function for restarting CFlexPeriodic timer.
+// Action depends the value of iFirstTicksLeft;
+// >0 -- Add timestamp to iFirstTimestamps
+// <0 -- Add timestamp to iSecondTimestamps
+// =0 -- Add timestamp to iFirstTimestamps AND iSecondTimestamps AND restart
+// the timer with iSecondInterval
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::RestartTimer( TAny* aArgument )
+ {
+ __ASSERT_ALWAYS(
+ aArgument != NULL,
+ User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
+
+ TRestartInfo* info = reinterpret_cast<TRestartInfo*>( aArgument );
+
+ __ASSERT_ALWAYS(
+ info->iTimer != NULL &&
+ info->iFirstTimestamps != NULL &&
+ info->iSecondTimestamps != NULL,
+ User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
+
+ // Add current time to timestamps
+ // Data is copied by RArray - no need to use heap
+ TTime now;
+ now.UniversalTime();
+
+ TInt ticks( info->iFirstTicksLeft-- ); // Update the ticks
+ TInt err( KErrNone );
+ if ( ticks > 0 )
+ {
+ err = info->iFirstTimestamps->Append( now );
+ }
+ else if ( ticks < 0 )
+ {
+ err = info->iSecondTimestamps->Append( now );
+ }
+ else // ticks == 0
+ {
+ // Set the timestamps.
+ // 1st timer settings expiration time is the starting time of the
+ // second timer settings. Add timestamp to both arrays.
+ err = info->iFirstTimestamps->Append( now );
+ __ASSERT_ALWAYS(
+ err == KErrNone,
+ User::Panic( KTestFlexTimerPanicCategory, err ) );
+ err = info->iSecondTimestamps->Append( now );
+
+ // Restart the timer
+ info->iTimer->Cancel();
+ info->iTimer->Start(
+ info->iSecondInterval,
+ info->iSecondInterval,
+ TCallBack( RestartTimer, info ) );
+ }
+ __ASSERT_ALWAYS(
+ err == KErrNone,
+ User::Panic( KTestFlexTimerPanicCategory, err ) );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TCallBack function for trying to configure timer in callback.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureTimer( TAny* aArgument )
+ {
+ __ASSERT_ALWAYS(
+ aArgument != NULL,
+ User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
+
+ TConfigureInfo* info = reinterpret_cast<TConfigureInfo*>( aArgument );
+
+ const TTimeIntervalMicroSeconds32 delayWindow32( info->iDelayWindow );
+ const TTimeIntervalMicroSeconds32 intervalWindow32( info->iIntervalWindow );
+
+ const TTimeIntervalMicroSeconds delayWindow64( info->iDelayWindow );
+ const TTimeIntervalMicroSeconds intervalWindow64( info->iIntervalWindow );
+
+ info->iConfigResult32 = info->iTimer->Configure( delayWindow32,
+ intervalWindow32);
+
+ info->iConfigResult64 = info->iTimer->Configure( delayWindow64,
+ intervalWindow64);
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TCallBack function for starting a flexible periodic timer.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartTimer( TAny* aArgument )
+ {
+ __ASSERT_ALWAYS(
+ aArgument != NULL,
+ User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
+
+ const TTimeIntervalMicroSeconds32 KTimerDelay( 2000000 );
+ const TTimeIntervalMicroSeconds32 KTimerInterval( 2000000 );
+
+ CFlexPeriodic* timer = reinterpret_cast<CFlexPeriodic*>( aArgument );
+
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( StartTimer, timer )
+ );
+
+ return KErrNone;
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// ___ _ _ _ ____ ____ ___ ____ _ _ ___ ____ _ _ _ _ ____ . ____
+// | | |\/| |___ [__ | |__| |\/| |__] |___ | | |\ | | ' [__
+// | | | | |___ ___] | | | | | | | |__| | \| |___ ___]
+//
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// Verify that the timestamps are expired at window.
+//
+// Note that the timer resolution is 1 sec, so, the actual expiration time can
+// be later than set.
+// ---------------------------------------------------------------------------
+//
+TBool CTestFlexPeriodic::AreTimestampsAtWindow(
+ const RArray<TTime>& aTimestamps,
+ const TTimeIntervalMicroSeconds32& aDelay,
+ const TTimeIntervalMicroSeconds32& aInterval,
+ const TTimeIntervalMicroSeconds32& aDelayWindow,
+ const TTimeIntervalMicroSeconds32& aIntervalWindow )
+ {
+ __ASSERT_ALWAYS(
+ aTimestamps.Count() >= 2 &&
+ aDelay.Int() >= 0 &&
+ aInterval.Int() >= 0 &&
+ aDelayWindow.Int() >= 0 &&
+ aIntervalWindow.Int() >= 0,
+ User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
+
+ // Timestamps are correct unless proved otherwise
+ TBool ret = ETrue;
+
+ // For the 1st expiration is delay
+ TTimeIntervalMicroSeconds delay;
+ delay = aTimestamps[1].MicroSecondsFrom( aTimestamps[0] );
+ RDebug::Print( _L("Timer delay %Ld"), delay.Int64() );
+
+ if ( delay < aDelay.Int() - aDelayWindow.Int() ||
+ delay > aDelay.Int() + KTimerResolution )
+ {
+ ret = EFalse;
+ }
+
+ // The rest of the expirations are intervals
+ for ( TInt i( 2 ); i < aTimestamps.Count(); ++i )
+ {
+ TTimeIntervalMicroSeconds interval;
+ interval = aTimestamps[i].MicroSecondsFrom( aTimestamps[i-1] );
+ RDebug::Print( _L("Timer interval %Ld"), interval.Int64() );
+
+ if ( interval < aInterval.Int() - aIntervalWindow.Int() ||
+ interval > aInterval.Int() + KTimerResolution )
+ {
+ ret = EFalse;
+ }
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// Convert the intervals from 64 bit to 32 bit and call 32 bit checking
+// function.
+// ---------------------------------------------------------------------------
+//
+TBool CTestFlexPeriodic::AreTimestampsAtWindow(
+ const RArray<TTime>& aTimestamps,
+ const TTimeIntervalMicroSeconds& aDelay,
+ const TTimeIntervalMicroSeconds& aInterval,
+ const TTimeIntervalMicroSeconds& aDelayWindow,
+ const TTimeIntervalMicroSeconds& aIntervalWindow )
+ {
+ __ASSERT_ALWAYS(
+ I64HIGH( aDelay.Int64() ) == 0 &&
+ I64HIGH( aInterval.Int64() ) == 0 &&
+ I64HIGH( aDelayWindow.Int64() ) == 0 &&
+ I64HIGH( aIntervalWindow.Int64() ) == 0,
+ User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
+
+ TTimeIntervalMicroSeconds32 delay( I64INT( aDelay.Int64() ) );
+ TTimeIntervalMicroSeconds32 interval( I64INT( aInterval.Int64() ) );
+ TTimeIntervalMicroSeconds32 delayWindow( I64INT( aDelayWindow.Int64() ) );
+ TTimeIntervalMicroSeconds32 intervalWindow( I64INT( aIntervalWindow.Int64() ) );
+
+ return AreTimestampsAtWindow( aTimestamps,
+ delay,
+ interval,
+ delayWindow,
+ intervalWindow );
+ }
+
+// ---------------------------------------------------------------------------
+// Compare are timestamp arrays same
+// ---------------------------------------------------------------------------
+//
+TBool CTestFlexPeriodic::AreTimestampsSame(
+ const RArray<TTime>& aLeft,
+ const RArray<TTime>& aRight )
+ {
+ TBool ret( ETrue );
+ if ( aLeft.Count() == aRight.Count() )
+ {
+ for ( TInt i( 0 ); i < aLeft.Count(); ++i )
+ {
+ if ( aLeft[i] != aRight[i] )
+ { // Different timestamp has been found
+ ret = EFalse;
+ break;
+ }
+ }
+ }
+ else
+ { // Arrays has different number of timestamps.
+ ret = EFalse;
+ }
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// ___ ____ _ _ ___ _ ____ ___ ____ ____ _ _ _ _ ____ . ____
+// | |___ |\/| |__] | |__| | |___ |___ | | |\ | | ' [__
+// | |___ | | | |___ | | | |___ | |__| | \| |___ ___]
+//
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// Configure window sizes - template function
+//
+// Timers are designed so that the 1st timer will test that the delay is
+// correct and the 2nd timer will test that the interval is correct
+// ---------------------------------------------------------------------------
+template <class firstType, class secondType>
+TInt CTestFlexPeriodic::ConfigureWindowL( TTestResult& aResult )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const firstType KFirstDelay( 3000000 ); // 3 sec
+ const firstType KFirstInterval( 2000000 ); // 2 sec
+ const firstType KFirstDelayWindow( 0 ); // no window
+ const firstType KFirstIntervalWindow( 1500000 ); // 1.5 sec
+
+ const secondType KSecondDelay( 3500000 ); // 3.5 sec
+ const secondType KSecondInterval( 1000000 ); // 1 sec
+ const secondType KSecondDelayWindow( 1500000 ); // 1.5 sec
+ const secondType KSecondIntervalWindow( 0 ); // no window
+
+ const TUint KTestRunTime( 10000000 ); // 10 sec
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // Create, configure and start the flexible periodic timer
+ RArray<TTime> firstTimestamps;
+ CFlexPeriodic* firstTimer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( firstTimer );
+ firstTimer->Configure( KFirstDelayWindow, KFirstIntervalWindow );
+ firstTimer->Start(
+ KFirstDelay,
+ KFirstInterval,
+ TCallBack( AddTimestamp, &firstTimestamps ) );
+
+ RArray<TTime> secondTimestamps;
+ CFlexPeriodic* secondTimer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( secondTimer );
+ secondTimer->Configure( KSecondDelayWindow, KSecondIntervalWindow );
+ secondTimer->Start(
+ KSecondDelay,
+ KSecondInterval,
+ TCallBack( AddTimestamp, &secondTimestamps ) );
+
+ // Initialize timer expiration time array with starting time to
+ // ease analysing of data.
+ TTime startTime;
+ startTime.UniversalTime();
+ firstTimestamps.Append( startTime );
+ secondTimestamps.Append( startTime );
+
+ // The execution will be pending here while active scheduler is running...
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Analyze results
+ aResult.SetResult( KErrNone, _L("Test case passed") );
+
+ // Check the 1st timer expiration time
+ if ( !AreTimestampsAtWindow(
+ firstTimestamps,
+ KFirstDelay,
+ KFirstInterval,
+ KFirstDelayWindow,
+ KFirstIntervalWindow ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. First timer not in window.") );
+ }
+
+ // Check the 2nd timer expiration time
+ else if ( !AreTimestampsAtWindow(
+ secondTimestamps,
+ KSecondDelay,
+ KSecondInterval,
+ KSecondDelayWindow,
+ KSecondIntervalWindow ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Second timer not in window.") );
+ }
+
+ // Check that both timers are expired at the same time
+ else if ( !AreTimestampsSame( firstTimestamps, secondTimestamps ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Timers are not expired at the same time.") );
+ }
+
+ // Clean up
+ secondTimer->Cancel();
+ secondTimestamps.Close();
+ CleanupStack::PopAndDestroy( secondTimer );
+
+ firstTimer->Cancel();
+ firstTimestamps.Close();
+ CleanupStack::PopAndDestroy( firstTimer );
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Configure window sizes and start timer with given values - template
+// function
+// ---------------------------------------------------------------------------
+template <class configureType, class startType>
+void CTestFlexPeriodic::ConfigureAndStartTimerL(
+ RArray<TTime>& aTimestamps,
+ TInt64 aDelay,
+ TInt64 aInterval,
+ TInt64 aDelayWindow,
+ TInt64 aIntervalWindow )
+ {
+ const startType KDelay( aDelay );
+ const startType KInterval( aInterval );
+ const configureType KDelayWindow( aDelayWindow );
+ const configureType KIntervalWindow( aIntervalWindow );
+
+ const TUint KTestRunTime( 3000000 );
+
+ TTime now;
+ now.UniversalTime();
+ aTimestamps.Append( now );
+
+ // Create and start the flexible periodic timer
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+ timer->Configure( KDelayWindow, KIntervalWindow );
+ timer->Start( KDelay, KInterval, TCallBack( AddTimestamp, &aTimestamps ) );
+
+ // The execution will be pending here while active scheduler is running...
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Clean up
+ timer->Cancel();
+ CleanupStack::PopAndDestroy( timer );
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start timer with NULL callback
+// ---------------------------------------------------------------------------
+//
+template<class startType>
+TInt CTestFlexPeriodic::StartWithNullCallBackL(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const startType KTimerDelay( 1000000 );
+ const startType KTimerInterval( 1000000 );
+
+ TInt(* nullCallback)(TAny*) = NULL;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 31 (EFlexPeriodicCallbackFunctionIsNull)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 31 );
+
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( nullCallback, NULL ) );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timer->Cancel();
+ CleanupStack::PopAndDestroy( timer );
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// Panic thread after a few seconds
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::DoPanicL(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const TTimeIntervalMicroSeconds32 KTimerDelay( 1000000 );
+ const TTimeIntervalMicroSeconds32 KTimerInterval( 1000000 );
+ const TTimeIntervalMicroSeconds32 KTestRunTime( 3000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( DoNothing, NULL ) );
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ User::Panic(_L("Die die die!"), 0xDEAD);
+
+ // We should NEVER be here...
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timer->Cancel();
+ CleanupStack::PopAndDestroy( timer );
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// ____ _ _ _ _ _ _ _ ___ _ _ ____ ____ ____ ___
+// |__/ | | |\ | | |\ | | |__| |__/ |___ |__| | \
+// | \ |__| | \| | | \| | | | | \ |___ | | |__/
+//
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// Run test case in own thread
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::RunInThread(
+ RThread& aThread,
+ TTestCaseArguments& aArguments )
+ {
+ // RThread::Create() parameters
+ const TInt stackSize = 1024;
+ const TInt heapMinSize = 1024;
+ const TInt heapMaxSize = 1024;
+
+ TBuf<8> processName;
+ processName.Format( _L("%x"), &aArguments.iResult );
+
+ // Create the thread
+ TInt ret = aThread.Create(
+ processName,
+ RunTestCase,
+ stackSize,
+ heapMinSize,
+ heapMaxSize,
+ &aArguments,
+ EOwnerProcess );
+
+ // Start execution of the thread
+ aThread.Resume();
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// Create cleanup stack
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::RunTestCase( TAny* aArgument )
+ {
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+
+ // Out of memory assert
+ __ASSERT_ALWAYS(
+ cleanup != NULL,
+ User::Panic( KTestFlexTimerPanicCategory, KErrNoMemory ) );
+
+ TRAPD( err, CTestFlexPeriodic::RunTestCaseL( aArgument ) );
+
+ delete cleanup;
+ return err;
+ }
+
+// ---------------------------------------------------------------------------
+// Create scheduler and run the test case
+// ---------------------------------------------------------------------------
+//
+void CTestFlexPeriodic::RunTestCaseL( TAny* aArgument )
+ {
+ // Create and install active scheduler
+ CActiveScheduler* scheduler = scheduler = new (ELeave) CActiveScheduler;
+ CleanupStack::PushL( scheduler );
+ CActiveScheduler::Install( scheduler );
+
+ // Parse the arguments
+ TTestCaseArguments* args = reinterpret_cast<TTestCaseArguments*>( aArgument );
+
+ // Call the function pointer with given arguments
+ TInt ret = (*(args->iTestFunction))(args->iResult, args->iCallback );
+ User::LeaveIfError( ret );
+
+ // Clean up
+ CleanupStack::PopAndDestroy( scheduler );
+ }
+
+// ---------------------------------------------------------------------------
+// ___ ____ ____ ___ ____ ____ ____ ____ ____
+// | |___ [__ | | |__| [__ |___ [__
+// | |___ ___] | |___ | | ___] |___ ___]
+//
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start one CFlexPeriodic and wait for few expirations.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartOneTimerL(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const TTimeIntervalMicroSeconds32 KTickInterval( 1000000 ); // 1 sec
+ const TUint KTestRunTime( 5000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // Storage for flexible periodic timer timestamps
+ RArray<TTime> timestamps;
+
+ // Create and start the flexible periodic timer
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+ timer->Start(
+ KTickInterval,
+ KTickInterval,
+ TCallBack( AddTimestamp, ×tamps ) );
+
+ // Initialize timer expiration time array with starting time to
+ // ease analysing of data.
+ TTime startTime;
+ startTime.UniversalTime();
+ timestamps.Append( startTime );
+
+ // The execution will be pending here while active scheduler is running...
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Analyze results
+ aResult.SetResult( KErrNone, _L("Test case passed") );
+
+ // Only start time in timestamp array
+ if ( timestamps.Count() == 1 )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. No timer expired.") );
+ }
+
+ // Check that the timers are expired at maximum delay due there are only
+ // one timer, so, no alignment can be happened.
+ if ( !AreTimestampsAtWindow( timestamps, KTickInterval, KTickInterval, 0, 0 ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Timer not in maximum window.") );
+ }
+
+ // Clean up
+ timer->Cancel();
+ timestamps.Close();
+ CleanupStack::PopAndDestroy( timer );
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start one CFlexPeriodic and wait for few expirations.
+// Give also Error callback function.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartOneTimerWithErrorCbL(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const TTimeIntervalMicroSeconds32 KTickInterval( 1000000 ); // 1 sec
+ const TUint KTestRunTime( 5000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // Storage for flexible periodic timer timestamps
+ RArray<TTime> timestamps;
+
+ // Create and start the flexible periodic timer
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+ timer->Start(
+ KTickInterval,
+ KTickInterval,
+ TCallBack( AddTimestamp, ×tamps ),
+ TCallBack( PanicClient, NULL ) );
+
+ // Initialize timer expiration time array with starting time to
+ // ease analysing of data.
+ TTime startTime;
+ startTime.UniversalTime();
+ timestamps.Append( startTime );
+
+ // The execution will be pending here while active scheduler is running...
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Analyze results
+ aResult.SetResult( KErrNone, _L("Test case passed") );
+
+ // Only start time in timestamp array
+ if ( timestamps.Count() == 1 )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. No timer expired.") );
+ }
+
+ // Check that the timers are expired at maximum delay due there are only
+ // one timer, so, no alignment can be happened.
+ if ( !AreTimestampsAtWindow( timestamps, KTickInterval, KTickInterval, 0, 0 ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Timer not in maximum window.") );
+ }
+
+ // Clean up
+ timer->Cancel();
+ timestamps.Close();
+ CleanupStack::PopAndDestroy( timer );
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start one CFlexPeriodic, cancel it and restart it in callback
+// function.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::CallbackRestartL(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const TTimeIntervalMicroSeconds KTickInterval( 1000000 ); // 1 sec
+ const TTimeIntervalMicroSeconds KTick2ndInterval( 2000000 ); // 2 sec
+ const TUint KTestRunTime( 10000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ RArray<TTime> firstTimestamps;
+ RArray<TTime> secondTimestamps;
+
+ TRestartInfo info;
+ info.iTimer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ info.iFirstTicksLeft = 1;
+ info.iFirstTimestamps = &firstTimestamps;
+ info.iSecondTimestamps = &secondTimestamps;
+ info.iSecondInterval = KTick2ndInterval;
+
+ // Create and start the flexible periodic timer
+ CleanupStack::PushL( info.iTimer );
+ info.iTimer->Start(
+ KTickInterval,
+ KTickInterval,
+ TCallBack( RestartTimer, &info ) );
+
+ // Initialize timer expiration time array with starting time to
+ // ease analysing of data.
+ TTime startTime;
+ startTime.UniversalTime();
+ firstTimestamps.Append( startTime );
+
+ // The execution will be pending here while active scheduler is running...
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Analyze results
+ aResult.SetResult( KErrNone, _L("Test case passed") );
+
+ // Check the 1st timer expiration time
+ if ( !AreTimestampsAtWindow( firstTimestamps, KTickInterval, KTickInterval, 0, 0 ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Pre-reset timer not in maximum window.") );
+ }
+
+ // Check the rest of timers
+ else if ( !AreTimestampsAtWindow( secondTimestamps, KTick2ndInterval, KTick2ndInterval, 0, 0 ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Post-reset timer not in maximum window.") );
+ }
+
+ // Clean up
+ info.iTimer->Cancel();
+ firstTimestamps.Close();
+ secondTimestamps.Close();
+ CleanupStack::PopAndDestroy( info.iTimer );
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Configure window sizes - 32 bit
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureWindow32L(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ return ConfigureWindowL<TTimeIntervalMicroSeconds32,TTimeIntervalMicroSeconds32>( aResult );
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Configure window sizes - 64 bit
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureWindow64L(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ return ConfigureWindowL<TTimeIntervalMicroSeconds,TTimeIntervalMicroSeconds>( aResult );
+ }
+
+// ---------------------------------------------------------------------------
+// OK TEST CASE: Configure window sizes - mixed 32 bit and 64 bit
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureWindowMixL(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ return ConfigureWindowL<TTimeIntervalMicroSeconds32,TTimeIntervalMicroSeconds>( aResult );
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Configure after timer has started
+// The test case is divided into following parts:
+// 1) Remove slack from the heartbeat to make it sure that timer's default
+// windows does not cause the drifting of the timer.
+// 2) Start timer, try to configure it, verify that configure has not been
+// changed (no alignment should be made by heartbeat)
+// 3) Cancel the timer and start it with a callback that tries to configure
+// it while in callback, check the results
+// 4) Verify that the configuration stil works by happened timer alignment
+// by the heartbeat
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureAfterStartL(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+
+ // Heartbeat timer
+ // Use 1us to adjust the engine's timer. 0 returns immediately.
+ const TTimeIntervalMicroSeconds32 KHeartbeatDelay( 1 );
+ const TTimeIntervalMicroSeconds32 KHeartbeatInterval( 1000000 );
+ const TTimeIntervalMicroSeconds32 KHeartbeatDelayWindow( 0 );
+ const TTimeIntervalMicroSeconds32 KHeartbeatIntervalWindow( 0 );
+
+ // Timer under test
+ const TTimeIntervalMicroSeconds32 KTimerDelayNow( 0 );
+ const TTimeIntervalMicroSeconds32 KTimerDelay( 2000000 );
+ const TTimeIntervalMicroSeconds32 KTimerInterval( 2000000 );
+ const TTimeIntervalMicroSeconds32 KTimerInitialDelayWindow( 0 );
+ const TTimeIntervalMicroSeconds32 KTimerInitialIntervalWindow( 0 );
+
+ const TTimeIntervalMicroSeconds32 KTimerDelayWindow32( 1500000 );
+ const TTimeIntervalMicroSeconds32 KTimerIntervalWindow32( 1500000 );
+
+ const TTimeIntervalMicroSeconds KTimerDelayWindow64( 1500000 );
+ const TTimeIntervalMicroSeconds KTimerIntervalWindow64( 1500000 );
+
+ const TUint KConfigNokTestRunTime( 7000000 );
+ const TUint KTestCbConfigRunTime( KHeartbeatInterval.Int() );
+ const TUint KConfigOkTestRunTime( 4000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // Create, configure and initialize and start the heartbeat
+ // This timer is used for checking that the timer under test is reacting
+ // correctly to configurations.
+ RArray<TTime> heartbeatTimes;
+ CFlexPeriodic* heartbeat = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( heartbeat );
+ heartbeat->Configure( KHeartbeatDelayWindow, KHeartbeatIntervalWindow );
+ heartbeat->Start(
+ KHeartbeatDelay,
+ KHeartbeatInterval,
+ TCallBack( AddTimestamp, &heartbeatTimes ) );
+
+ // Remove the slack from timer start up -- wait till next second
+ const TInt64 KSecondInMicroSeconds( 1000000 );
+ TTime now;
+ now.UniversalTime();
+ heartbeatTimes.Append( now );
+ TUint slack( I64LOW( KSecondInMicroSeconds - now.Int64() % KSecondInMicroSeconds ) );
+
+ // // ___ _____
+ WaitL( slack ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Create and start the flexible periodic timer
+ RArray<TTime> timestamps;
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+ timer->Configure( KTimerInitialDelayWindow, KTimerInitialIntervalWindow );
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( AddTimestamp, ×tamps ) );
+
+ aResult.SetResult( KErrNone, _L("Test case passed") );
+
+ if ( timer->Configure( KTimerDelayWindow32, KTimerIntervalWindow32 ) != KErrInUse )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. 32 bit configure didn't return KErrInUse") );
+ }
+ else if ( timer->Configure( KTimerDelayWindow64, KTimerIntervalWindow64 ) != KErrInUse )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. 64 bit configure didn't return KErrInUse") );
+ }
+
+ // Initialize timer expiration time array with starting time to
+ // ease analysing of data.
+ now.UniversalTime();
+ timestamps.Append( now );
+ // // ___ _____
+ WaitL( KConfigNokTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Check the 1st timer expiration time
+ RDebug::Print( _L("Timer:") );
+ if ( !AreTimestampsAtWindow(
+ timestamps,
+ KTimerDelay,
+ KTimerInterval,
+ KTimerInitialDelayWindow,
+ KTimerInitialIntervalWindow ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Configuration changed after start. ") );
+ }
+
+ // Restart the timer to try configuration while callback
+ timer->Cancel();
+
+ TConfigureInfo configInfo;
+ configInfo.iTimer = timer;
+ configInfo.iDelayWindow = KTimerDelayWindow32.Int();
+ configInfo.iIntervalWindow = KTimerIntervalWindow32.Int();
+ configInfo.iConfigResult32 = 0xDEADBEEF; // Initialize result
+ configInfo.iConfigResult64 = 0xDEADBEEF; // Initialize result
+
+ timer->Start(
+ KTimerDelayNow,
+ KTimerInterval,
+ TCallBack( ConfigureTimer, &configInfo ) );
+
+ // // ___ _____
+ WaitL( KTestCbConfigRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ timer->Cancel();
+
+ RDebug::Print( _L("configInfo.iConfigResult32=%d (0x%x)"), configInfo.iConfigResult32, configInfo.iConfigResult32 );
+ RDebug::Print( _L("configInfo.iConfigResult64=%d (0x%x)"), configInfo.iConfigResult64, configInfo.iConfigResult64 );
+
+ // Analyze the results
+ if ( configInfo.iConfigResult32 != KErrInUse )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. 32 bit configure in callback didn't return KErrInUse") );
+ }
+ else if ( configInfo.iConfigResult64 != KErrInUse )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. 64 bit configure in callback didn't return KErrInUse") );
+ }
+
+ // Test that the configuration still works
+ RArray<TTime> secondTimestamps;
+ now.UniversalTime();
+ secondTimestamps.Append( now );
+
+ if ( timer->Configure( KTimerDelayWindow32, KTimerIntervalWindow32 ) != KErrNone )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Configure failed.") );
+ }
+ else
+ {
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( AddTimestamp, &secondTimestamps ));
+
+ // // ___ _____
+ WaitL( KConfigOkTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Check timestamps, they should be the same as heartbeat
+ RDebug::Print( _L("secondTimestamps:") );
+ if ( !AreTimestampsAtWindow(
+ secondTimestamps,
+ KHeartbeatInterval, // Heartbeat was running already
+ KHeartbeatInterval,
+ KHeartbeatInterval, // There can be adjustement with 1st expiration
+ 0 ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Configure does not work.") );
+ }
+ }
+
+ RDebug::Print( _L("Heartbeat:") );
+ if ( !AreTimestampsAtWindow(
+ heartbeatTimes,
+ KHeartbeatDelay,
+ KHeartbeatInterval,
+ KHeartbeatDelayWindow,
+ KHeartbeatIntervalWindow ) )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Heartbeat failure.") );
+ }
+
+ // Clean up
+ timestamps.Close();
+ secondTimestamps.Close();
+ timer->Cancel();
+ CleanupStack::PopAndDestroy( timer );
+
+ heartbeatTimes.Close();
+ heartbeat->Cancel();
+ CleanupStack::PopAndDestroy( heartbeat );
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start a running timer again.
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartAfterStartL(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const TTimeIntervalMicroSeconds32 KTimerDelay( 2000000 );
+ const TTimeIntervalMicroSeconds32 KTimerInterval( 2000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+
+ // This start should work...
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( DoNothing, NULL ) );
+
+ // ... and next start should panic with
+ // Panic category: "E32USER-CBase"
+ // Panic reason: 42 (attempt to active CActive when a request is still
+ // outstanding)
+
+ // Set panic code 42 to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason(
+ CTestModuleIf::EPanic,
+ 42 );
+
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( DoNothing, NULL ) );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason(
+ CTestModuleIf::ENormal,
+ KErrNone );
+
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timer->Cancel();
+ CleanupStack::PopAndDestroy( timer );
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start a running timer again in callback function
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartInCallbackL(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ // Constants
+ const TTimeIntervalMicroSeconds32 KTimerDelay( 1000000 );
+ const TTimeIntervalMicroSeconds32 KTimerInterval( 1000000 );
+ const TTimeIntervalMicroSeconds32 KTestRunTime( 3000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
+ CleanupStack::PushL( timer );
+
+ // The callback should panic with
+ // Panic category: "E32USER-CBase"
+ // Panic reason: 42 (attempt to active CActive when a request is still
+ // outstanding)
+
+ // Set panic code 42 to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason(
+ CTestModuleIf::EPanic,
+ 42 );
+
+ timer->Start(
+ KTimerDelay,
+ KTimerInterval,
+ TCallBack( StartTimer, timer ) );
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timer->Cancel();
+ CleanupStack::PopAndDestroy( timer );
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start with negative delay, 32 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithNegativeDelay32L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 6 (EFlexPeriodicDelayLessThanZero)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 6 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start with zero interval, 32 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithZeroInterval32L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( 0 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 7 (EFlexPeriodicIntervalTooSmall)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KAllowedValue,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start with negative interval, 32 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithNegativeInterval32L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 7 (EFlexPeriodicIntervalTooSmall)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KAllowedValue,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start with negative delay, 64 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithNegativeDelay64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 6 (EFlexPeriodicDelayLessThanZero)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 6 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start with zero interval, 64 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithZeroInterval64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( 0 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 7 (EFlexPeriodicIntervalTooSmall)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KAllowedValue,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start with negative interval, 64 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithNegativeInterval64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 7 (EFlexPeriodicIntervalTooSmall)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KAllowedValue,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Configure timer with negative delay window, 32 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureWithNegativeDelayWindow32L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 8 (EFlexPeriodicDelayWindowLessThanZero)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 8 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KAllowedValue,
+ KAllowedValue,
+ KIllegalValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Configure timer with negative interval window, 32 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureWithNegativeIntervalWindow32L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 9 (EFlexPeriodicIntervalWindowLessThanZero)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 9 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KAllowedValue,
+ KAllowedValue,
+ KAllowedValue,
+ KIllegalValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Configure timer with negative delay window, 64 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureWithNegativeDelayWindow64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 8 (EFlexPeriodicDelayWindowLessThanZero)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 8 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KAllowedValue,
+ KAllowedValue,
+ KIllegalValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Configure timer with negative interval window, 64 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ConfigureWithNegativeIntervalWindow64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt KIllegalValue( -1 );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 9 (EFlexPeriodicIntervalWindowLessThanZero)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 9 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KAllowedValue,
+ KAllowedValue,
+ KAllowedValue,
+ KIllegalValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start with minimum and maximum values
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithMinAndMaxL(
+ TTestResult& aResult,
+ CTestFlexTimer* /* aCallback */ )
+ {
+ __UHEAP_MARK;
+
+ const TInt KMinimumDelayValue( 0 );
+ const TInt KMinimumIntervalValue( 1 );
+ const TInt KNormalValue( 1000000 );
+ const TInt KMaximum32BitValue( 0x7FFFFFFF );
+
+// const TInt64 KLarge64BitValue( 0x6FFFFFFFFFFFFFFF ); // Should not panic (till few years)
+
+ // Years * Days * Hours * Minutes * Seconds * Microseconds
+ const TInt64 KLarge64BitValue( ((TInt64)(1)) * 365 * 24 * 60 * 60 * 1000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ RArray<TTime> timestamps;
+
+ TTime now;
+ now.UniversalTime();
+
+ // > DEBUG
+ TTimeIntervalMicroSeconds longLongInterval( KLarge64BitValue );
+ now += longLongInterval;
+ TDateTime date;
+ date = now.DateTime();
+ // < DEBUG
+
+ // Start with min delay, 32 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KMinimumDelayValue,
+ KNormalValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ if ( !AreTimestampsAtWindow(
+ timestamps,
+ TTimeIntervalMicroSeconds32( KMinimumDelayValue ),
+ TTimeIntervalMicroSeconds32( KNormalValue ),
+ TTimeIntervalMicroSeconds32( KNormalValue ),
+ TTimeIntervalMicroSeconds32( KNormalValue ) ) )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit min delay failed") );
+ }
+ timestamps.Reset();
+
+ // Start with max delay, 32 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KMaximum32BitValue,
+ KNormalValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ // Only one timestamp (the start time) is allowed
+ if ( timestamps.Count() > 1 )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit max delay failed") );
+ }
+ timestamps.Reset();
+
+ // Start with min interval, 32 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KNormalValue,
+ KMinimumIntervalValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ if ( !AreTimestampsAtWindow(
+ timestamps,
+ TTimeIntervalMicroSeconds32( KNormalValue ),
+ TTimeIntervalMicroSeconds32( KMinimumIntervalValue ),
+ TTimeIntervalMicroSeconds32( KNormalValue ),
+ TTimeIntervalMicroSeconds32( KNormalValue ) ) )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit min interval failed") );
+ }
+ timestamps.Reset();
+
+ // Start with max interval, 32 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
+ timestamps,
+ KNormalValue,
+ KMaximum32BitValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ if ( !AreTimestampsAtWindow(
+ timestamps,
+ TTimeIntervalMicroSeconds32( KNormalValue ),
+ TTimeIntervalMicroSeconds32( KMaximum32BitValue ),
+ TTimeIntervalMicroSeconds32( KNormalValue ),
+ TTimeIntervalMicroSeconds32( KNormalValue ) ) )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit min interval failed") );
+ }
+ timestamps.Reset();
+
+ // Start with min delay, 64 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KMinimumDelayValue,
+ KNormalValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ if ( !AreTimestampsAtWindow(
+ timestamps,
+ TTimeIntervalMicroSeconds( KMinimumDelayValue ),
+ TTimeIntervalMicroSeconds( KNormalValue ),
+ TTimeIntervalMicroSeconds( KNormalValue ),
+ TTimeIntervalMicroSeconds( KNormalValue ) ) )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit min delay failed") );
+ }
+ timestamps.Reset();
+
+ // Start with large delay, 64 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KLarge64BitValue,
+ KNormalValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ // Only one timestamp (the start time) is allowed
+ if ( timestamps.Count() > 1 )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit max delay failed") );
+ }
+ timestamps.Reset();
+
+ // Start with min interval, 64 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KNormalValue,
+ KMinimumIntervalValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ if ( !AreTimestampsAtWindow(
+ timestamps,
+ TTimeIntervalMicroSeconds( KNormalValue ),
+ TTimeIntervalMicroSeconds( KMinimumIntervalValue ),
+ TTimeIntervalMicroSeconds( KNormalValue ),
+ TTimeIntervalMicroSeconds( KNormalValue ) ) )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit min interval failed") );
+ }
+ timestamps.Reset();
+
+ // Start with large interval, 64 bit
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KNormalValue,
+ KLarge64BitValue,
+ KNormalValue,
+ KNormalValue );
+ // Validate results
+ // AreTimestampsAtWindow() does not accept values over 0xFFFFFFFF.
+ // However, this is not a problem due there should be only the timestamps
+ // of start time and delay expiration; 32 bit value can be used instead of
+ // the real interval.
+ if ( !AreTimestampsAtWindow(
+ timestamps,
+ TTimeIntervalMicroSeconds( KNormalValue ),
+ TTimeIntervalMicroSeconds( KMaximum32BitValue ),
+ TTimeIntervalMicroSeconds( KNormalValue ),
+ TTimeIntervalMicroSeconds( KNormalValue ) ) )
+ {
+ aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit max interval failed") );
+ }
+ timestamps.Reset();
+
+ // If test execution is here, we'll passed
+ aResult.SetResult( KErrNone, _L("Test case passed") );
+
+ // Clean up
+ timestamps.Close();
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start timer with maximum delay, 64 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithMaximumDelay64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt64 KIllegalValue( 0x7FFFFFFFFFFFFFFF );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 24 (EFlexTimerServerIllegalTimerValue)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 24 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start timer with maximum interval, 64 bit interface
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithMaximumInterval64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ const TInt KAllowedValue( 1 );
+ const TInt64 KIllegalValue( 0x7FFFFFFFFFFFFFFF );
+
+ RArray<TTime> timestamps;
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // ConfigureAndStartTimerL should panic:
+ // Category: "CFlexPeriodic"
+ // Reason: 24 (EFlexTimerServerIllegalTimerValue)
+ // Set the panic code to acceptable exit reason
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 24 );
+
+ ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
+ timestamps,
+ KAllowedValue,
+ KIllegalValue,
+ KAllowedValue,
+ KAllowedValue );
+
+ // No panic, change result back to normal
+ aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
+ aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
+
+ // Clean up
+ timestamps.Close();
+
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start timer with NULL callback (32 bit)
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithNullCallBack32L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ return StartWithNullCallBackL<TTimeIntervalMicroSeconds32>( aResult, aCallback );
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Start timer with NULL callback (64 bit)
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::StartWithNullCallBack64L(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ return StartWithNullCallBackL<TTimeIntervalMicroSeconds>( aResult, aCallback );
+ }
+
+// ---------------------------------------------------------------------------
+// TEST CASE: Client crashes
+// 1) Start two timers in separate threads
+// 2) The 1st timer will panic after a while
+// 3) Check that the 2nd timer is ok -> server works OK
+// ---------------------------------------------------------------------------
+//
+TInt CTestFlexPeriodic::ClientCrashL(
+ TTestResult& aResult,
+ CTestFlexTimer* aCallback )
+ {
+ __UHEAP_MARK;
+
+ // Must be bigger than ClientCrashL and StartOneTimerL
+ const TTimeIntervalMicroSeconds32 KTestRunTime( 6000000 );
+
+ // Default result if anything leaves i.e. no analyze done.
+ aResult.SetResult( KErrGeneral, _L("Test case leaved") );
+
+ // Start test case ClientCrashL
+ RThread threadA;
+ TTestResult resultA;
+ TTestCaseArguments caseA = { DoPanicL, resultA, aCallback };
+ RunInThread( threadA, caseA );
+
+ // Start test case StartOneTimerL
+ RThread threadB;
+ TTestResult resultB;
+ TTestCaseArguments caseB = { StartOneTimerL, resultB, aCallback };
+ RunInThread( threadB, caseB );
+
+ // // ___ _____
+ WaitL( KTestRunTime ); // // // //_ // // //
+ //_//_// // // // //
+
+ // Analyze results
+ aResult.SetResult(KErrNone, _L("Test case passed.") );
+
+ // ClientCrashL should be paniced with reason 0xDEAD
+ if ( threadA.ExitType() != EExitPanic || threadA.ExitReason() != 0xDEAD )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Client did not panic (correctly).") );
+ }
+ // StartOneTimerL should be finished ok
+ else if ( resultB.iResult != KErrNone || threadB.ExitType() == EExitPanic )
+ {
+ aResult.SetResult(
+ KErrGeneral,
+ _L("Test case failed. Timer failed.") );
+ }
+
+ threadA.Close();
+ threadB.Close();
+ __UHEAP_MARKEND;
+
+ return KErrNone;
+ }