keepalive/flextimer/test/testflextimer/src/testflexperiodic.cpp
changeset 32 5c4486441ae6
equal deleted inserted replaced
31:c16e04725da3 32:5c4486441ae6
       
     1 /*
       
     2 * ============================================================================
       
     3 *  Name        : testflexperiodic.cpp
       
     4 *  Part of     : src / testflextimer
       
     5 *  Description : STIF test cases for CFlexPeriodic timer.
       
     6 *  Version     : %version: 1 %
       
     7 *
       
     8 *  Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     9 *  All rights reserved.
       
    10 *  This component and the accompanying materials are made available
       
    11 *  under the terms of the License "Eclipse Public License v1.0"
       
    12 *  which accompanies this distribution, and is available
       
    13 *  at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
    14 *
       
    15 *  Initial Contributors:
       
    16 *  Nokia Corporation - initial contribution.
       
    17 *
       
    18 *  Contributors:
       
    19 *  Nokia Corporation
       
    20 * ============================================================================
       
    21 * Template version: 4.1
       
    22 */
       
    23 
       
    24 #include <e32debug.h>               // for RDebug
       
    25 #include <flexperiodic.h>           // for CFlexPeriodic
       
    26 #include <stiftesteventinterface.h> // for TEventIf 
       
    27 #include "testflextimer.h"          // for global constants
       
    28 #include "testflexperiodic.h"
       
    29 
       
    30 /**
       
    31  *  Timer can be expired 1 sec late
       
    32  *  
       
    33  *  Note! Definition
       
    34  *  
       
    35  *      const TTimeIntervalMicroSeconds32 KTimerResolution( 1000000 );
       
    36  * 
       
    37  * will cause writable static data due non-trivial constructor of 
       
    38  * TTimeIntervalMicroSeconds32.
       
    39  *  
       
    40  */
       
    41 const TInt KTimerResolution( 1000000 );
       
    42 
       
    43 // ======== LOCAL FUNCTIONS ========
       
    44 
       
    45 // ======== MEMBER FUNCTIONS ========
       
    46 
       
    47 // ---------------------------------------------------------------------------
       
    48 // Constructor
       
    49 // ---------------------------------------------------------------------------
       
    50 //
       
    51 CTestFlexPeriodic::CTestFlexPeriodic()
       
    52     {
       
    53     }
       
    54 
       
    55 // ---------------------------------------------------------------------------
       
    56 // Destructor
       
    57 // ---------------------------------------------------------------------------
       
    58 //
       
    59 CTestFlexPeriodic::~CTestFlexPeriodic()
       
    60     {
       
    61     }
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // _ _ _ ____ _ ___    _    ____ ____ ___  
       
    65 // | | | |__| |  |     |    |  | |  | |__] 
       
    66 // |_|_| |  | |  |     |___ |__| |__| |    
       
    67 //                                         
       
    68 // ---------------------------------------------------------------------------
       
    69 
       
    70 // ---------------------------------------------------------------------------
       
    71 // Start scheduler for given time.
       
    72 // ---------------------------------------------------------------------------
       
    73 //
       
    74 void CTestFlexPeriodic::WaitL( TTimeIntervalMicroSeconds32 aPeriod )
       
    75     {
       
    76     CPeriodic* watchdog = CPeriodic::NewL( CActive::EPriorityStandard );
       
    77     CleanupStack::PushL( watchdog );
       
    78     watchdog->Start( aPeriod, aPeriod, TCallBack( StopScheduler, NULL ) );
       
    79     
       
    80     // Start scheduler. Wait here until the timer expires and stops the
       
    81     // scheduler.
       
    82     CActiveScheduler::Start();
       
    83     
       
    84     // Clean-up
       
    85     watchdog->Cancel();
       
    86     CleanupStack::PopAndDestroy( watchdog );
       
    87     }
       
    88 
       
    89 // ---------------------------------------------------------------------------
       
    90 // TCallBack function to stop the scheduler.
       
    91 // ---------------------------------------------------------------------------
       
    92 //
       
    93 TInt CTestFlexPeriodic::StopScheduler( TAny* /* aArgument */ )
       
    94     {
       
    95     CActiveScheduler::Stop();
       
    96     return KErrNone;
       
    97     }
       
    98 
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // ____ ____ _    _    ___  ____ ____ _  _ ____ 
       
   102 // |    |__| |    |    |__] |__| |    |_/  [__  
       
   103 // |___ |  | |___ |___ |__] |  | |___ | \_ ___] 
       
   104 //                                              
       
   105 // ---------------------------------------------------------------------------
       
   106 
       
   107 // ---------------------------------------------------------------------------
       
   108 // TCallBack function that does nothing. Not ment to be called - just to 
       
   109 // fulfill the interface.
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 TInt CTestFlexPeriodic::DoNothing( TAny* /* aArgument */ )
       
   113     {
       
   114     return KErrNone;
       
   115     }
       
   116 
       
   117 // ---------------------------------------------------------------------------
       
   118 // TCallBack function that panics testcase if it get called.
       
   119 // ---------------------------------------------------------------------------
       
   120 //
       
   121 TInt CTestFlexPeriodic::PanicClient( TAny* /* aArgument */ )
       
   122     {
       
   123     User::Panic(_L("NotCalled CB got called"), 0xDEAD);
       
   124     return KErrNone;
       
   125     }
       
   126 // ---------------------------------------------------------------------------
       
   127 // TCallBack function for adding time stamp to an RArray of TTimes.
       
   128 // ---------------------------------------------------------------------------
       
   129 //
       
   130 TInt CTestFlexPeriodic::AddTimestamp( TAny* aArgument )
       
   131     {
       
   132     __ASSERT_ALWAYS(
       
   133         aArgument != NULL,
       
   134         User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
       
   135 
       
   136     //RDebug::Print( _L("CTestFlexPeriodic::AddTimestamp()") );
       
   137     
       
   138     RArray<TTime>* times =  reinterpret_cast<RArray<TTime>*>( aArgument );
       
   139 
       
   140     TTime now;
       
   141     now.UniversalTime();
       
   142 
       
   143     TInt err = times->Append( now ); // Data is copied by RArray
       
   144     __ASSERT_ALWAYS(
       
   145         err == KErrNone,
       
   146         User::Panic( KTestFlexTimerPanicCategory, err ) );
       
   147 
       
   148     return KErrNone;
       
   149     }
       
   150 
       
   151 // ---------------------------------------------------------------------------
       
   152 // TCallBack function for restarting CFlexPeriodic timer.
       
   153 // Action depends the value of iFirstTicksLeft;
       
   154 // >0 -- Add timestamp to iFirstTimestamps 
       
   155 // <0 -- Add timestamp to iSecondTimestamps
       
   156 // =0 -- Add timestamp to iFirstTimestamps AND iSecondTimestamps AND restart
       
   157 //       the timer with iSecondInterval
       
   158 // ---------------------------------------------------------------------------
       
   159 //
       
   160 TInt CTestFlexPeriodic::RestartTimer( TAny* aArgument )
       
   161     {
       
   162     __ASSERT_ALWAYS(
       
   163         aArgument != NULL,
       
   164         User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
       
   165 
       
   166     TRestartInfo* info =  reinterpret_cast<TRestartInfo*>( aArgument );
       
   167 
       
   168     __ASSERT_ALWAYS(
       
   169         info->iTimer != NULL && 
       
   170         info->iFirstTimestamps != NULL && 
       
   171         info->iSecondTimestamps != NULL,
       
   172         User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
       
   173     
       
   174     // Add current time to timestamps
       
   175     // Data is copied by RArray - no need to use heap
       
   176     TTime now;
       
   177     now.UniversalTime();
       
   178     
       
   179     TInt ticks( info->iFirstTicksLeft-- ); // Update the ticks
       
   180     TInt err( KErrNone );
       
   181     if ( ticks > 0 )
       
   182         {
       
   183         err = info->iFirstTimestamps->Append( now );
       
   184         }
       
   185     else if ( ticks < 0 )
       
   186         {
       
   187         err = info->iSecondTimestamps->Append( now );
       
   188         }
       
   189     else // ticks == 0
       
   190         {
       
   191         // Set the timestamps.
       
   192         // 1st timer settings expiration time is the starting time of the
       
   193         // second timer settings. Add timestamp to both arrays.
       
   194         err = info->iFirstTimestamps->Append( now );
       
   195         __ASSERT_ALWAYS(
       
   196             err == KErrNone,
       
   197             User::Panic( KTestFlexTimerPanicCategory, err ) );
       
   198         err = info->iSecondTimestamps->Append( now );
       
   199 
       
   200         // Restart the timer
       
   201         info->iTimer->Cancel();
       
   202         info->iTimer->Start(
       
   203             info->iSecondInterval,
       
   204             info->iSecondInterval, 
       
   205             TCallBack( RestartTimer, info ) );
       
   206         }
       
   207     __ASSERT_ALWAYS(
       
   208         err == KErrNone,
       
   209         User::Panic( KTestFlexTimerPanicCategory, err ) );
       
   210 
       
   211     return KErrNone;
       
   212     }
       
   213 
       
   214 // ---------------------------------------------------------------------------
       
   215 // TCallBack function for trying to configure timer in callback.
       
   216 // ---------------------------------------------------------------------------
       
   217 //
       
   218 TInt CTestFlexPeriodic::ConfigureTimer( TAny* aArgument )
       
   219     {
       
   220     __ASSERT_ALWAYS(
       
   221         aArgument != NULL,
       
   222         User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
       
   223 
       
   224     TConfigureInfo* info =  reinterpret_cast<TConfigureInfo*>( aArgument );
       
   225 
       
   226     const TTimeIntervalMicroSeconds32 delayWindow32( info->iDelayWindow );
       
   227     const TTimeIntervalMicroSeconds32 intervalWindow32( info->iIntervalWindow );
       
   228 
       
   229     const TTimeIntervalMicroSeconds delayWindow64( info->iDelayWindow );
       
   230     const TTimeIntervalMicroSeconds intervalWindow64( info->iIntervalWindow );
       
   231 
       
   232     info->iConfigResult32 = info->iTimer->Configure( delayWindow32,
       
   233                                                      intervalWindow32);
       
   234 
       
   235     info->iConfigResult64 = info->iTimer->Configure( delayWindow64,
       
   236                                                      intervalWindow64);
       
   237 
       
   238     return KErrNone;
       
   239     }
       
   240 
       
   241 // ---------------------------------------------------------------------------
       
   242 // TCallBack function for starting a flexible periodic timer.
       
   243 // ---------------------------------------------------------------------------
       
   244 //
       
   245 TInt CTestFlexPeriodic::StartTimer( TAny* aArgument )
       
   246     {
       
   247     __ASSERT_ALWAYS(
       
   248         aArgument != NULL,
       
   249         User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
       
   250 
       
   251     const TTimeIntervalMicroSeconds32 KTimerDelay( 2000000 );
       
   252     const TTimeIntervalMicroSeconds32 KTimerInterval( 2000000 );
       
   253 
       
   254     CFlexPeriodic* timer =  reinterpret_cast<CFlexPeriodic*>( aArgument );
       
   255 
       
   256     timer->Start(
       
   257         KTimerDelay,
       
   258         KTimerInterval,
       
   259         TCallBack( StartTimer, timer )
       
   260         );
       
   261 
       
   262     return KErrNone;
       
   263     }
       
   264 
       
   265 
       
   266 
       
   267 // ---------------------------------------------------------------------------
       
   268 // ___ _ _  _ ____ ____ ___ ____ _  _ ___     ____ _  _ _  _ ____ . ____ 
       
   269 //  |  | |\/| |___ [__   |  |__| |\/| |__]    |___ |  | |\ | |    ' [__  
       
   270 //  |  | |  | |___ ___]  |  |  | |  | |       |    |__| | \| |___   ___] 
       
   271 //
       
   272 // ---------------------------------------------------------------------------
       
   273 
       
   274 // ---------------------------------------------------------------------------
       
   275 // Verify that the timestamps are expired at window.
       
   276 //
       
   277 // Note that the timer resolution is 1 sec, so, the actual expiration time can
       
   278 // be later than set.
       
   279 // ---------------------------------------------------------------------------
       
   280 //
       
   281 TBool CTestFlexPeriodic::AreTimestampsAtWindow( 
       
   282     const RArray<TTime>& aTimestamps,
       
   283     const TTimeIntervalMicroSeconds32& aDelay,
       
   284     const TTimeIntervalMicroSeconds32& aInterval,
       
   285     const TTimeIntervalMicroSeconds32& aDelayWindow,
       
   286     const TTimeIntervalMicroSeconds32& aIntervalWindow )
       
   287     {
       
   288     __ASSERT_ALWAYS(
       
   289         aTimestamps.Count() >= 2 && 
       
   290         aDelay.Int() >= 0 &&
       
   291         aInterval.Int() >= 0 &&
       
   292         aDelayWindow.Int() >= 0 &&
       
   293         aIntervalWindow.Int() >= 0,
       
   294         User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
       
   295 
       
   296     // Timestamps are correct unless proved otherwise 
       
   297     TBool ret = ETrue;
       
   298 
       
   299     // For the 1st expiration is delay
       
   300     TTimeIntervalMicroSeconds delay;
       
   301     delay = aTimestamps[1].MicroSecondsFrom( aTimestamps[0] );
       
   302     RDebug::Print( _L("Timer delay %Ld"), delay.Int64() );
       
   303 
       
   304     if ( delay < aDelay.Int() - aDelayWindow.Int() || 
       
   305          delay > aDelay.Int() + KTimerResolution )
       
   306         {
       
   307         ret = EFalse;
       
   308         }
       
   309 
       
   310     // The rest of the expirations are intervals
       
   311     for ( TInt i( 2 ); i < aTimestamps.Count(); ++i )
       
   312         {
       
   313         TTimeIntervalMicroSeconds interval;
       
   314         interval = aTimestamps[i].MicroSecondsFrom( aTimestamps[i-1] );
       
   315         RDebug::Print( _L("Timer interval %Ld"), interval.Int64() );
       
   316 
       
   317         if ( interval < aInterval.Int() - aIntervalWindow.Int() || 
       
   318              interval > aInterval.Int() + KTimerResolution )
       
   319             {
       
   320             ret = EFalse;
       
   321             }
       
   322         }
       
   323 
       
   324     return ret;
       
   325     }
       
   326 
       
   327 // ---------------------------------------------------------------------------
       
   328 // Convert the intervals from 64 bit to 32 bit and call 32 bit checking 
       
   329 // function.
       
   330 // ---------------------------------------------------------------------------
       
   331 //
       
   332 TBool CTestFlexPeriodic::AreTimestampsAtWindow( 
       
   333     const RArray<TTime>& aTimestamps,
       
   334     const TTimeIntervalMicroSeconds& aDelay,
       
   335     const TTimeIntervalMicroSeconds& aInterval,
       
   336     const TTimeIntervalMicroSeconds& aDelayWindow,
       
   337     const TTimeIntervalMicroSeconds& aIntervalWindow )
       
   338     {
       
   339     __ASSERT_ALWAYS(
       
   340         I64HIGH( aDelay.Int64() ) == 0 &&
       
   341         I64HIGH( aInterval.Int64() ) == 0 &&
       
   342         I64HIGH( aDelayWindow.Int64() ) == 0 &&
       
   343         I64HIGH( aIntervalWindow.Int64() ) == 0,
       
   344         User::Panic( KTestFlexTimerPanicCategory, KErrArgument ) );
       
   345 
       
   346     TTimeIntervalMicroSeconds32 delay( I64INT( aDelay.Int64() ) );
       
   347     TTimeIntervalMicroSeconds32 interval( I64INT( aInterval.Int64() ) );
       
   348     TTimeIntervalMicroSeconds32 delayWindow( I64INT( aDelayWindow.Int64() ) );
       
   349     TTimeIntervalMicroSeconds32 intervalWindow( I64INT( aIntervalWindow.Int64() ) );
       
   350 
       
   351     return AreTimestampsAtWindow( aTimestamps, 
       
   352                                   delay,
       
   353                                   interval,
       
   354                                   delayWindow,
       
   355                                   intervalWindow );
       
   356     }
       
   357 
       
   358 // ---------------------------------------------------------------------------
       
   359 // Compare are timestamp arrays same
       
   360 // ---------------------------------------------------------------------------
       
   361 //
       
   362 TBool CTestFlexPeriodic::AreTimestampsSame(
       
   363     const RArray<TTime>& aLeft,
       
   364     const RArray<TTime>& aRight )
       
   365     {
       
   366     TBool ret( ETrue );
       
   367     if ( aLeft.Count() == aRight.Count() )
       
   368         {
       
   369         for ( TInt i( 0 ); i < aLeft.Count(); ++i )
       
   370             {
       
   371             if ( aLeft[i] != aRight[i] )
       
   372                 { // Different timestamp has been found
       
   373                 ret = EFalse;
       
   374                 break;
       
   375                 }
       
   376             }
       
   377         }
       
   378     else
       
   379         { // Arrays has different number of timestamps.
       
   380         ret = EFalse;
       
   381         }
       
   382 
       
   383     return ret;
       
   384     }
       
   385 
       
   386 // ---------------------------------------------------------------------------
       
   387 // ___ ____ _  _ ___  _    ____ ___ ____    ____ _  _ _  _ ____ . ____ 
       
   388 //  |  |___ |\/| |__] |    |__|  |  |___    |___ |  | |\ | |    ' [__  
       
   389 //  |  |___ |  | |    |___ |  |  |  |___    |    |__| | \| |___   ___] 
       
   390 //
       
   391 // ---------------------------------------------------------------------------
       
   392 
       
   393 // ---------------------------------------------------------------------------
       
   394 // Configure window sizes - template function
       
   395 // 
       
   396 // Timers are designed so that the 1st timer will test that the delay is
       
   397 // correct and the 2nd timer will test that the interval is correct
       
   398 // ---------------------------------------------------------------------------
       
   399 template <class firstType, class secondType>
       
   400 TInt CTestFlexPeriodic::ConfigureWindowL( TTestResult& aResult )
       
   401     {
       
   402     __UHEAP_MARK;
       
   403 
       
   404     // Constants
       
   405     const firstType KFirstDelay( 3000000 );             // 3 sec
       
   406     const firstType KFirstInterval( 2000000 );          // 2 sec
       
   407     const firstType KFirstDelayWindow( 0 );             // no window
       
   408     const firstType KFirstIntervalWindow( 1500000 );    // 1.5 sec
       
   409 
       
   410     const secondType KSecondDelay( 3500000 );           // 3.5 sec
       
   411     const secondType KSecondInterval( 1000000 );        // 1 sec
       
   412     const secondType KSecondDelayWindow( 1500000 );     // 1.5 sec
       
   413     const secondType KSecondIntervalWindow( 0 );        // no window
       
   414 
       
   415     const TUint KTestRunTime( 10000000 ); // 10 sec
       
   416 
       
   417     // Default result if anything leaves i.e. no analyze done.
       
   418     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
   419 
       
   420     // Create, configure and start the flexible periodic timer
       
   421     RArray<TTime> firstTimestamps;
       
   422     CFlexPeriodic* firstTimer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   423     CleanupStack::PushL( firstTimer );
       
   424     firstTimer->Configure( KFirstDelayWindow, KFirstIntervalWindow );
       
   425     firstTimer->Start( 
       
   426         KFirstDelay, 
       
   427         KFirstInterval, 
       
   428         TCallBack( AddTimestamp, &firstTimestamps ) );
       
   429 
       
   430     RArray<TTime> secondTimestamps;
       
   431     CFlexPeriodic* secondTimer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   432     CleanupStack::PushL( secondTimer );
       
   433     secondTimer->Configure( KSecondDelayWindow, KSecondIntervalWindow );
       
   434     secondTimer->Start( 
       
   435         KSecondDelay, 
       
   436         KSecondInterval,
       
   437         TCallBack( AddTimestamp, &secondTimestamps ) );
       
   438 
       
   439     // Initialize timer expiration time array with starting time to 
       
   440     // ease analysing of data.
       
   441     TTime startTime;
       
   442     startTime.UniversalTime();
       
   443     firstTimestamps.Append( startTime );
       
   444     secondTimestamps.Append( startTime );
       
   445 
       
   446     // The execution will be pending here while active scheduler is running...
       
   447 
       
   448                             //    //  ___     _____
       
   449     WaitL( KTestRunTime ); // // // //_ // //  //
       
   450                           //_//_// //  // //  //
       
   451 
       
   452     // Analyze results
       
   453     aResult.SetResult( KErrNone, _L("Test case passed") );
       
   454 
       
   455     // Check the 1st timer expiration time
       
   456     if ( !AreTimestampsAtWindow( 
       
   457             firstTimestamps, 
       
   458             KFirstDelay, 
       
   459             KFirstInterval, 
       
   460             KFirstDelayWindow, 
       
   461             KFirstIntervalWindow ) )
       
   462         {
       
   463         aResult.SetResult( 
       
   464             KErrGeneral, 
       
   465             _L("Test case failed. First timer not in window.") );
       
   466         }
       
   467 
       
   468     // Check the 2nd timer expiration time
       
   469     else if ( !AreTimestampsAtWindow( 
       
   470             secondTimestamps, 
       
   471             KSecondDelay, 
       
   472             KSecondInterval, 
       
   473             KSecondDelayWindow, 
       
   474             KSecondIntervalWindow ) )
       
   475         {
       
   476         aResult.SetResult( 
       
   477             KErrGeneral, 
       
   478             _L("Test case failed. Second timer not in window.") );
       
   479         }
       
   480     
       
   481     // Check that both timers are expired at the same time
       
   482     else if ( !AreTimestampsSame( firstTimestamps, secondTimestamps ) )
       
   483         {
       
   484         aResult.SetResult( 
       
   485             KErrGeneral, 
       
   486             _L("Test case failed. Timers are not expired at the same time.") );
       
   487         }
       
   488 
       
   489     // Clean up
       
   490     secondTimer->Cancel();
       
   491     secondTimestamps.Close();
       
   492     CleanupStack::PopAndDestroy( secondTimer );
       
   493 
       
   494     firstTimer->Cancel();
       
   495     firstTimestamps.Close();
       
   496     CleanupStack::PopAndDestroy( firstTimer );
       
   497     __UHEAP_MARKEND;
       
   498 
       
   499     return KErrNone;
       
   500     }
       
   501 
       
   502 // ---------------------------------------------------------------------------
       
   503 // Configure window sizes and start timer with given values - template 
       
   504 // function
       
   505 // ---------------------------------------------------------------------------
       
   506 template <class configureType, class startType>
       
   507 void CTestFlexPeriodic::ConfigureAndStartTimerL( 
       
   508     RArray<TTime>& aTimestamps,
       
   509     TInt64 aDelay,
       
   510     TInt64 aInterval,
       
   511     TInt64 aDelayWindow,
       
   512     TInt64 aIntervalWindow )
       
   513     {
       
   514     const startType KDelay( aDelay );
       
   515     const startType KInterval( aInterval );
       
   516     const configureType KDelayWindow( aDelayWindow );
       
   517     const configureType KIntervalWindow( aIntervalWindow );
       
   518 
       
   519     const TUint KTestRunTime( 3000000 );
       
   520 
       
   521     TTime now;
       
   522     now.UniversalTime();
       
   523     aTimestamps.Append( now );
       
   524 
       
   525     // Create and start the flexible periodic timer
       
   526     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   527     CleanupStack::PushL( timer );
       
   528     timer->Configure( KDelayWindow, KIntervalWindow );
       
   529     timer->Start( KDelay, KInterval, TCallBack( AddTimestamp, &aTimestamps ) );
       
   530     
       
   531     // The execution will be pending here while active scheduler is running...
       
   532 
       
   533                             //    //  ___     _____
       
   534     WaitL( KTestRunTime ); // // // //_ // //  //
       
   535                           //_//_// //  // //  //
       
   536 
       
   537     // Clean up
       
   538     timer->Cancel();
       
   539     CleanupStack::PopAndDestroy( timer );
       
   540     }
       
   541 
       
   542 // ---------------------------------------------------------------------------
       
   543 // TEST CASE: Start timer with NULL callback 
       
   544 // ---------------------------------------------------------------------------
       
   545 //
       
   546 template<class startType>
       
   547 TInt CTestFlexPeriodic::StartWithNullCallBackL(
       
   548     TTestResult& aResult, 
       
   549     CTestFlexTimer* aCallback )
       
   550     {
       
   551     __UHEAP_MARK;
       
   552 
       
   553     // Constants
       
   554     const startType KTimerDelay( 1000000 );
       
   555     const startType KTimerInterval( 1000000 );
       
   556 
       
   557     TInt(* nullCallback)(TAny*) = NULL;
       
   558     
       
   559     // Default result if anything leaves i.e. no analyze done.
       
   560     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
   561 
       
   562     // ConfigureAndStartTimerL should panic:
       
   563     //  Category: "CFlexPeriodic" 
       
   564     //  Reason:   31 (EFlexPeriodicCallbackFunctionIsNull)
       
   565     // Set the panic code to acceptable exit reason
       
   566     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 31 );
       
   567     
       
   568     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   569     CleanupStack::PushL( timer );
       
   570     timer->Start( 
       
   571         KTimerDelay, 
       
   572         KTimerInterval, 
       
   573         TCallBack( nullCallback, NULL ) );
       
   574 
       
   575     // No panic, change result back to normal
       
   576     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
   577     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
   578     
       
   579     // Clean up
       
   580     timer->Cancel();
       
   581     CleanupStack::PopAndDestroy( timer );
       
   582 
       
   583     __UHEAP_MARKEND;
       
   584 
       
   585     return KErrNone;
       
   586     }
       
   587 
       
   588 // ---------------------------------------------------------------------------
       
   589 // Panic thread after a few seconds
       
   590 // ---------------------------------------------------------------------------
       
   591 //
       
   592 TInt CTestFlexPeriodic::DoPanicL(
       
   593     TTestResult& aResult, 
       
   594     CTestFlexTimer* /* aCallback */ )
       
   595     {
       
   596     __UHEAP_MARK;
       
   597 
       
   598     // Constants
       
   599     const TTimeIntervalMicroSeconds32 KTimerDelay( 1000000 );
       
   600     const TTimeIntervalMicroSeconds32 KTimerInterval( 1000000 );
       
   601     const TTimeIntervalMicroSeconds32 KTestRunTime( 3000000 );
       
   602 
       
   603     // Default result if anything leaves i.e. no analyze done.
       
   604     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
   605 
       
   606     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   607     CleanupStack::PushL( timer );
       
   608     timer->Start( 
       
   609         KTimerDelay, 
       
   610         KTimerInterval, 
       
   611         TCallBack( DoNothing, NULL ) );
       
   612 
       
   613                             //    //  ___     _____
       
   614     WaitL( KTestRunTime ); // // // //_ // //  //
       
   615                           //_//_// //  // //  //
       
   616 
       
   617     User::Panic(_L("Die die die!"), 0xDEAD);
       
   618 
       
   619     // We should NEVER be here...
       
   620     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
   621     
       
   622     // Clean up
       
   623     timer->Cancel();
       
   624     CleanupStack::PopAndDestroy( timer );
       
   625 
       
   626     __UHEAP_MARKEND;
       
   627 
       
   628     return KErrNone;
       
   629     }
       
   630 
       
   631 // ---------------------------------------------------------------------------
       
   632 // ____ _  _ _  _    _ _  _    ___ _  _ ____ ____ ____ ___  
       
   633 // |__/ |  | |\ |    | |\ |     |  |__| |__/ |___ |__| |  \ 
       
   634 // |  \ |__| | \|    | | \|     |  |  | |  \ |___ |  | |__/ 
       
   635 //
       
   636 // ---------------------------------------------------------------------------
       
   637 
       
   638 // ---------------------------------------------------------------------------
       
   639 // Run test case in own thread
       
   640 // ---------------------------------------------------------------------------
       
   641 //
       
   642 TInt CTestFlexPeriodic::RunInThread( 
       
   643     RThread& aThread, 
       
   644     TTestCaseArguments& aArguments )
       
   645     {
       
   646     // RThread::Create() parameters
       
   647     const TInt stackSize = 1024;
       
   648     const TInt heapMinSize = 1024;
       
   649     const TInt heapMaxSize = 1024;
       
   650 
       
   651     TBuf<8> processName;
       
   652     processName.Format( _L("%x"), &aArguments.iResult );
       
   653     
       
   654     // Create the thread
       
   655     TInt ret = aThread.Create(
       
   656         processName,
       
   657         RunTestCase, 
       
   658         stackSize,
       
   659         heapMinSize,
       
   660         heapMaxSize,
       
   661         &aArguments,
       
   662         EOwnerProcess );
       
   663 
       
   664     // Start execution of the thread
       
   665     aThread.Resume();
       
   666 
       
   667     return ret;
       
   668     }
       
   669 
       
   670 // ---------------------------------------------------------------------------
       
   671 // Create cleanup stack
       
   672 // ---------------------------------------------------------------------------
       
   673 //
       
   674 TInt CTestFlexPeriodic::RunTestCase( TAny* aArgument )
       
   675     {
       
   676     CTrapCleanup* cleanup = CTrapCleanup::New();
       
   677 
       
   678     // Out of memory assert
       
   679     __ASSERT_ALWAYS(
       
   680         cleanup != NULL, 
       
   681         User::Panic( KTestFlexTimerPanicCategory, KErrNoMemory ) );
       
   682     
       
   683     TRAPD( err, CTestFlexPeriodic::RunTestCaseL( aArgument ) );
       
   684 
       
   685     delete cleanup;
       
   686     return err;
       
   687     }
       
   688 
       
   689 // ---------------------------------------------------------------------------
       
   690 // Create scheduler and run the test case
       
   691 // ---------------------------------------------------------------------------
       
   692 //
       
   693 void CTestFlexPeriodic::RunTestCaseL( TAny* aArgument )
       
   694     {
       
   695     // Create and install active scheduler
       
   696     CActiveScheduler* scheduler = scheduler = new (ELeave) CActiveScheduler;
       
   697     CleanupStack::PushL( scheduler );
       
   698     CActiveScheduler::Install( scheduler );
       
   699     
       
   700     // Parse the arguments
       
   701     TTestCaseArguments* args = reinterpret_cast<TTestCaseArguments*>( aArgument );
       
   702     
       
   703     // Call the function pointer with given arguments
       
   704     TInt ret = (*(args->iTestFunction))(args->iResult, args->iCallback );
       
   705     User::LeaveIfError( ret );
       
   706 
       
   707     // Clean up
       
   708     CleanupStack::PopAndDestroy( scheduler );
       
   709     }
       
   710 
       
   711 // ---------------------------------------------------------------------------
       
   712 // ___ ____ ____ ___    ____ ____ ____ ____ ____ 
       
   713 //  |  |___ [__   |     |    |__| [__  |___ [__  
       
   714 //  |  |___ ___]  |     |___ |  | ___] |___ ___] 
       
   715 //
       
   716 // ---------------------------------------------------------------------------
       
   717 
       
   718 // ---------------------------------------------------------------------------
       
   719 // TEST CASE: Start one CFlexPeriodic and wait for few expirations.
       
   720 // ---------------------------------------------------------------------------
       
   721 //
       
   722 TInt CTestFlexPeriodic::StartOneTimerL( 
       
   723         TTestResult& aResult, 
       
   724         CTestFlexTimer* /* aCallback */ )
       
   725     {
       
   726     __UHEAP_MARK;
       
   727 
       
   728     // Constants
       
   729     const TTimeIntervalMicroSeconds32 KTickInterval( 1000000 ); // 1 sec
       
   730     const TUint KTestRunTime( 5000000 );
       
   731 
       
   732     // Default result if anything leaves i.e. no analyze done.
       
   733     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
   734 
       
   735     // Storage for flexible periodic timer timestamps
       
   736     RArray<TTime> timestamps;
       
   737 
       
   738     // Create and start the flexible periodic timer
       
   739     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   740     CleanupStack::PushL( timer );
       
   741     timer->Start( 
       
   742         KTickInterval, 
       
   743         KTickInterval, 
       
   744         TCallBack( AddTimestamp, &timestamps ) );
       
   745 
       
   746     // Initialize timer expiration time array with starting time to 
       
   747     // ease analysing of data.
       
   748     TTime startTime;
       
   749     startTime.UniversalTime();
       
   750     timestamps.Append( startTime );
       
   751     
       
   752     // The execution will be pending here while active scheduler is running...
       
   753 
       
   754                             //    //  ___     _____
       
   755     WaitL( KTestRunTime ); // // // //_ // //  //
       
   756                           //_//_// //  // //  //
       
   757 
       
   758     // Analyze results
       
   759     aResult.SetResult( KErrNone, _L("Test case passed") );
       
   760 
       
   761     // Only start time in timestamp array
       
   762     if ( timestamps.Count() == 1 )
       
   763         {
       
   764         aResult.SetResult( 
       
   765             KErrGeneral, 
       
   766             _L("Test case failed. No timer expired.") );
       
   767         }
       
   768 
       
   769     // Check that the timers are expired at maximum delay due there are only
       
   770     // one timer, so, no alignment can be happened.
       
   771     if ( !AreTimestampsAtWindow( timestamps, KTickInterval, KTickInterval, 0, 0 ) )
       
   772         {
       
   773         aResult.SetResult( 
       
   774             KErrGeneral, 
       
   775             _L("Test case failed. Timer not in maximum window.") );
       
   776         }
       
   777 
       
   778     // Clean up
       
   779     timer->Cancel();
       
   780     timestamps.Close();
       
   781     CleanupStack::PopAndDestroy( timer );
       
   782     __UHEAP_MARKEND;
       
   783 
       
   784     return KErrNone;
       
   785     }
       
   786 
       
   787 // ---------------------------------------------------------------------------
       
   788 // TEST CASE: Start one CFlexPeriodic and wait for few expirations.
       
   789 // Give also Error callback function.
       
   790 // ---------------------------------------------------------------------------
       
   791 //
       
   792 TInt CTestFlexPeriodic::StartOneTimerWithErrorCbL( 
       
   793         TTestResult& aResult, 
       
   794         CTestFlexTimer* /* aCallback */ )
       
   795     {
       
   796     __UHEAP_MARK;
       
   797 
       
   798     // Constants
       
   799     const TTimeIntervalMicroSeconds32 KTickInterval( 1000000 ); // 1 sec
       
   800     const TUint KTestRunTime( 5000000 );
       
   801 
       
   802     // Default result if anything leaves i.e. no analyze done.
       
   803     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
   804 
       
   805     // Storage for flexible periodic timer timestamps
       
   806     RArray<TTime> timestamps;
       
   807 
       
   808     // Create and start the flexible periodic timer
       
   809     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   810     CleanupStack::PushL( timer );
       
   811     timer->Start( 
       
   812         KTickInterval, 
       
   813         KTickInterval, 
       
   814         TCallBack( AddTimestamp, &timestamps ),
       
   815         TCallBack( PanicClient, NULL ) );
       
   816 
       
   817     // Initialize timer expiration time array with starting time to 
       
   818     // ease analysing of data.
       
   819     TTime startTime;
       
   820     startTime.UniversalTime();
       
   821     timestamps.Append( startTime );
       
   822     
       
   823     // The execution will be pending here while active scheduler is running...
       
   824 
       
   825                             //    //  ___     _____
       
   826     WaitL( KTestRunTime ); // // // //_ // //  //
       
   827                           //_//_// //  // //  //
       
   828 
       
   829     // Analyze results
       
   830     aResult.SetResult( KErrNone, _L("Test case passed") );
       
   831 
       
   832     // Only start time in timestamp array
       
   833     if ( timestamps.Count() == 1 )
       
   834         {
       
   835         aResult.SetResult( 
       
   836             KErrGeneral, 
       
   837             _L("Test case failed. No timer expired.") );
       
   838         }
       
   839 
       
   840     // Check that the timers are expired at maximum delay due there are only
       
   841     // one timer, so, no alignment can be happened.
       
   842     if ( !AreTimestampsAtWindow( timestamps, KTickInterval, KTickInterval, 0, 0 ) )
       
   843         {
       
   844         aResult.SetResult( 
       
   845             KErrGeneral, 
       
   846             _L("Test case failed. Timer not in maximum window.") );
       
   847         }
       
   848 
       
   849     // Clean up
       
   850     timer->Cancel();
       
   851     timestamps.Close();
       
   852     CleanupStack::PopAndDestroy( timer );
       
   853     __UHEAP_MARKEND;
       
   854 
       
   855     return KErrNone;
       
   856     }
       
   857 
       
   858 // ---------------------------------------------------------------------------
       
   859 // TEST CASE: Start one CFlexPeriodic, cancel it and restart it in callback
       
   860 // function.
       
   861 // ---------------------------------------------------------------------------
       
   862 //
       
   863 TInt CTestFlexPeriodic::CallbackRestartL( 
       
   864     TTestResult& aResult, 
       
   865     CTestFlexTimer* /* aCallback */ )
       
   866     {
       
   867     __UHEAP_MARK;
       
   868 
       
   869     // Constants
       
   870     const TTimeIntervalMicroSeconds KTickInterval( 1000000 ); // 1 sec
       
   871     const TTimeIntervalMicroSeconds KTick2ndInterval( 2000000 ); // 2 sec
       
   872     const TUint KTestRunTime( 10000000 );
       
   873 
       
   874     // Default result if anything leaves i.e. no analyze done.
       
   875     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
   876 
       
   877     RArray<TTime> firstTimestamps;
       
   878     RArray<TTime> secondTimestamps;
       
   879 
       
   880     TRestartInfo info;
       
   881     info.iTimer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
   882     info.iFirstTicksLeft = 1;
       
   883     info.iFirstTimestamps = &firstTimestamps;
       
   884     info.iSecondTimestamps = &secondTimestamps;
       
   885     info.iSecondInterval = KTick2ndInterval;
       
   886 
       
   887     // Create and start the flexible periodic timer
       
   888     CleanupStack::PushL( info.iTimer );
       
   889     info.iTimer->Start( 
       
   890         KTickInterval, 
       
   891         KTickInterval, 
       
   892         TCallBack( RestartTimer, &info ) );
       
   893 
       
   894     // Initialize timer expiration time array with starting time to 
       
   895     // ease analysing of data.
       
   896     TTime startTime;
       
   897     startTime.UniversalTime();
       
   898     firstTimestamps.Append( startTime );
       
   899     
       
   900     // The execution will be pending here while active scheduler is running...
       
   901 
       
   902                             //    //  ___     _____
       
   903     WaitL( KTestRunTime ); // // // //_ // //  //
       
   904                           //_//_// //  // //  //
       
   905 
       
   906     // Analyze results
       
   907     aResult.SetResult( KErrNone, _L("Test case passed") );
       
   908 
       
   909     // Check the 1st timer expiration time
       
   910     if ( !AreTimestampsAtWindow( firstTimestamps, KTickInterval, KTickInterval, 0, 0 ) )
       
   911         {
       
   912         aResult.SetResult( 
       
   913             KErrGeneral, 
       
   914             _L("Test case failed. Pre-reset timer not in maximum window.") );
       
   915         }
       
   916     
       
   917     // Check the rest of timers
       
   918     else if ( !AreTimestampsAtWindow( secondTimestamps, KTick2ndInterval, KTick2ndInterval, 0, 0 ) )
       
   919         {
       
   920         aResult.SetResult( 
       
   921             KErrGeneral, 
       
   922             _L("Test case failed. Post-reset timer not in maximum window.") );
       
   923         }
       
   924     
       
   925     // Clean up
       
   926     info.iTimer->Cancel();
       
   927     firstTimestamps.Close();
       
   928     secondTimestamps.Close();
       
   929     CleanupStack::PopAndDestroy( info.iTimer );
       
   930     __UHEAP_MARKEND;
       
   931 
       
   932     return KErrNone;
       
   933     }
       
   934 
       
   935 // ---------------------------------------------------------------------------
       
   936 // TEST CASE: Configure window sizes - 32 bit
       
   937 // ---------------------------------------------------------------------------
       
   938 //
       
   939 TInt CTestFlexPeriodic::ConfigureWindow32L( 
       
   940     TTestResult& aResult, 
       
   941     CTestFlexTimer* /* aCallback */ )
       
   942     {
       
   943     return ConfigureWindowL<TTimeIntervalMicroSeconds32,TTimeIntervalMicroSeconds32>( aResult );
       
   944     }
       
   945 
       
   946 // ---------------------------------------------------------------------------
       
   947 // TEST CASE: Configure window sizes - 64 bit
       
   948 // ---------------------------------------------------------------------------
       
   949 //
       
   950 TInt CTestFlexPeriodic::ConfigureWindow64L(
       
   951     TTestResult& aResult, 
       
   952     CTestFlexTimer* /* aCallback */ )
       
   953     {
       
   954     return ConfigureWindowL<TTimeIntervalMicroSeconds,TTimeIntervalMicroSeconds>( aResult );
       
   955     }
       
   956 
       
   957 // ---------------------------------------------------------------------------
       
   958 // OK TEST CASE: Configure window sizes - mixed 32 bit and 64 bit
       
   959 // ---------------------------------------------------------------------------
       
   960 //
       
   961 TInt CTestFlexPeriodic::ConfigureWindowMixL(
       
   962     TTestResult& aResult, 
       
   963     CTestFlexTimer* /* aCallback */ )
       
   964     {
       
   965     return ConfigureWindowL<TTimeIntervalMicroSeconds32,TTimeIntervalMicroSeconds>( aResult );
       
   966     }
       
   967 
       
   968 // ---------------------------------------------------------------------------
       
   969 // TEST CASE: Configure after timer has started 
       
   970 // The test case is divided into following parts:
       
   971 // 1) Remove slack from the heartbeat to make it sure that timer's default
       
   972 //    windows does not cause the drifting of the timer.
       
   973 // 2) Start timer, try to configure it, verify that configure has not been
       
   974 //    changed (no alignment should be made by heartbeat)
       
   975 // 3) Cancel the timer and start it with a callback that tries to configure
       
   976 //    it while in callback, check the results
       
   977 // 4) Verify that the configuration stil works by happened timer alignment
       
   978 //    by the heartbeat
       
   979 // ---------------------------------------------------------------------------
       
   980 //
       
   981 TInt CTestFlexPeriodic::ConfigureAfterStartL(
       
   982     TTestResult& aResult, 
       
   983     CTestFlexTimer* /* aCallback */ )
       
   984     {
       
   985     __UHEAP_MARK;
       
   986 
       
   987     // Constants
       
   988     
       
   989     // Heartbeat timer
       
   990     // Use 1us to adjust the engine's timer. 0 returns immediately.
       
   991     const TTimeIntervalMicroSeconds32 KHeartbeatDelay( 1 );
       
   992     const TTimeIntervalMicroSeconds32 KHeartbeatInterval( 1000000 );
       
   993     const TTimeIntervalMicroSeconds32 KHeartbeatDelayWindow( 0 );
       
   994     const TTimeIntervalMicroSeconds32 KHeartbeatIntervalWindow( 0 );
       
   995 
       
   996     // Timer under test
       
   997     const TTimeIntervalMicroSeconds32 KTimerDelayNow( 0 );
       
   998     const TTimeIntervalMicroSeconds32 KTimerDelay( 2000000 );
       
   999     const TTimeIntervalMicroSeconds32 KTimerInterval( 2000000 );
       
  1000     const TTimeIntervalMicroSeconds32 KTimerInitialDelayWindow( 0 );
       
  1001     const TTimeIntervalMicroSeconds32 KTimerInitialIntervalWindow( 0 );
       
  1002 
       
  1003     const TTimeIntervalMicroSeconds32 KTimerDelayWindow32( 1500000 );
       
  1004     const TTimeIntervalMicroSeconds32 KTimerIntervalWindow32( 1500000 );
       
  1005 
       
  1006     const TTimeIntervalMicroSeconds KTimerDelayWindow64( 1500000 );
       
  1007     const TTimeIntervalMicroSeconds KTimerIntervalWindow64( 1500000 );
       
  1008     
       
  1009     const TUint KConfigNokTestRunTime( 7000000 );
       
  1010     const TUint KTestCbConfigRunTime( KHeartbeatInterval.Int() );
       
  1011     const TUint KConfigOkTestRunTime( 4000000 );
       
  1012     
       
  1013     // Default result if anything leaves i.e. no analyze done.
       
  1014     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1015     
       
  1016     // Create, configure and initialize and start the heartbeat
       
  1017     // This timer is used for checking that the timer under test is reacting
       
  1018     // correctly to configurations.
       
  1019     RArray<TTime> heartbeatTimes;
       
  1020     CFlexPeriodic* heartbeat = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
  1021     CleanupStack::PushL( heartbeat );
       
  1022     heartbeat->Configure( KHeartbeatDelayWindow, KHeartbeatIntervalWindow );
       
  1023     heartbeat->Start( 
       
  1024         KHeartbeatDelay, 
       
  1025         KHeartbeatInterval, 
       
  1026         TCallBack( AddTimestamp, &heartbeatTimes ) );
       
  1027 
       
  1028     // Remove the slack from timer start up -- wait till next second
       
  1029     const TInt64 KSecondInMicroSeconds( 1000000 );
       
  1030     TTime now;
       
  1031     now.UniversalTime();
       
  1032     heartbeatTimes.Append( now );
       
  1033     TUint slack( I64LOW( KSecondInMicroSeconds - now.Int64() % KSecondInMicroSeconds ) );
       
  1034 
       
  1035                      //    //  ___     _____
       
  1036     WaitL( slack ); // // // //_ // //  //
       
  1037                    //_//_// //  // //  //
       
  1038 
       
  1039     // Create and start the flexible periodic timer
       
  1040     RArray<TTime> timestamps;
       
  1041     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
  1042     CleanupStack::PushL( timer );
       
  1043     timer->Configure( KTimerInitialDelayWindow, KTimerInitialIntervalWindow );
       
  1044     timer->Start( 
       
  1045         KTimerDelay, 
       
  1046         KTimerInterval, 
       
  1047         TCallBack( AddTimestamp, &timestamps ) );
       
  1048 
       
  1049     aResult.SetResult( KErrNone, _L("Test case passed") );
       
  1050 
       
  1051     if ( timer->Configure( KTimerDelayWindow32, KTimerIntervalWindow32 ) != KErrInUse )
       
  1052         {
       
  1053         aResult.SetResult( 
       
  1054             KErrGeneral, 
       
  1055             _L("Test case failed. 32 bit configure didn't return KErrInUse") );
       
  1056         }
       
  1057     else if ( timer->Configure( KTimerDelayWindow64, KTimerIntervalWindow64 ) != KErrInUse )
       
  1058         {
       
  1059         aResult.SetResult( 
       
  1060             KErrGeneral, 
       
  1061             _L("Test case failed. 64 bit configure didn't return KErrInUse") );
       
  1062         }
       
  1063 
       
  1064     // Initialize timer expiration time array with starting time to 
       
  1065     // ease analysing of data.
       
  1066     now.UniversalTime();
       
  1067     timestamps.Append( now );
       
  1068                                      //    //  ___     _____
       
  1069     WaitL( KConfigNokTestRunTime ); // // // //_ // //  //
       
  1070                                    //_//_// //  // //  //
       
  1071 
       
  1072     // Check the 1st timer expiration time
       
  1073     RDebug::Print( _L("Timer:") );
       
  1074     if ( !AreTimestampsAtWindow( 
       
  1075             timestamps, 
       
  1076             KTimerDelay,
       
  1077             KTimerInterval,
       
  1078             KTimerInitialDelayWindow,
       
  1079             KTimerInitialIntervalWindow ) )
       
  1080         {
       
  1081         aResult.SetResult( 
       
  1082             KErrGeneral, 
       
  1083             _L("Test case failed. Configuration changed after start. ") );
       
  1084         }
       
  1085 
       
  1086     // Restart the timer to try configuration while callback
       
  1087     timer->Cancel();
       
  1088 
       
  1089     TConfigureInfo configInfo;
       
  1090     configInfo.iTimer = timer;
       
  1091     configInfo.iDelayWindow = KTimerDelayWindow32.Int();
       
  1092     configInfo.iIntervalWindow = KTimerIntervalWindow32.Int();
       
  1093     configInfo.iConfigResult32 = 0xDEADBEEF; // Initialize result
       
  1094     configInfo.iConfigResult64 = 0xDEADBEEF; // Initialize result
       
  1095 
       
  1096     timer->Start(
       
  1097         KTimerDelayNow, 
       
  1098         KTimerInterval, 
       
  1099         TCallBack( ConfigureTimer, &configInfo ) );
       
  1100 
       
  1101                                     //    //  ___     _____
       
  1102     WaitL( KTestCbConfigRunTime ); // // // //_ // //  //
       
  1103                                   //_//_// //  // //  //
       
  1104 
       
  1105     timer->Cancel();
       
  1106 
       
  1107     RDebug::Print( _L("configInfo.iConfigResult32=%d (0x%x)"), configInfo.iConfigResult32, configInfo.iConfigResult32 );
       
  1108     RDebug::Print( _L("configInfo.iConfigResult64=%d (0x%x)"), configInfo.iConfigResult64, configInfo.iConfigResult64 );
       
  1109 
       
  1110     // Analyze the results
       
  1111     if ( configInfo.iConfigResult32 != KErrInUse )
       
  1112         {
       
  1113         aResult.SetResult( 
       
  1114             KErrGeneral, 
       
  1115             _L("Test case failed. 32 bit configure in callback didn't return KErrInUse") );
       
  1116         }
       
  1117     else if ( configInfo.iConfigResult64 != KErrInUse )
       
  1118         {
       
  1119         aResult.SetResult( 
       
  1120             KErrGeneral, 
       
  1121             _L("Test case failed. 64 bit configure in callback didn't return KErrInUse") );
       
  1122         }
       
  1123 
       
  1124     // Test that the configuration still works
       
  1125     RArray<TTime> secondTimestamps;
       
  1126     now.UniversalTime();
       
  1127     secondTimestamps.Append( now );
       
  1128 
       
  1129     if ( timer->Configure( KTimerDelayWindow32, KTimerIntervalWindow32 ) != KErrNone )
       
  1130         {
       
  1131         aResult.SetResult( 
       
  1132             KErrGeneral, 
       
  1133             _L("Test case failed. Configure failed.") );
       
  1134         }
       
  1135     else
       
  1136         {
       
  1137         timer->Start(
       
  1138             KTimerDelay,
       
  1139             KTimerInterval,
       
  1140             TCallBack( AddTimestamp, &secondTimestamps ));
       
  1141 
       
  1142                                         //    //  ___     _____
       
  1143         WaitL( KConfigOkTestRunTime ); // // // //_ // //  //
       
  1144                                       //_//_// //  // //  //
       
  1145 
       
  1146         // Check timestamps, they should be the same as heartbeat
       
  1147         RDebug::Print( _L("secondTimestamps:") );
       
  1148         if ( !AreTimestampsAtWindow( 
       
  1149                 secondTimestamps, 
       
  1150                 KHeartbeatInterval, // Heartbeat was running already 
       
  1151                 KHeartbeatInterval,
       
  1152                 KHeartbeatInterval, // There can be adjustement with 1st expiration 
       
  1153                 0 ) )
       
  1154             {
       
  1155             aResult.SetResult( 
       
  1156                 KErrGeneral, 
       
  1157                 _L("Test case failed. Configure does not work.") );
       
  1158             }
       
  1159         }
       
  1160 
       
  1161     RDebug::Print( _L("Heartbeat:") );
       
  1162     if ( !AreTimestampsAtWindow( 
       
  1163             heartbeatTimes, 
       
  1164             KHeartbeatDelay,
       
  1165             KHeartbeatInterval,
       
  1166             KHeartbeatDelayWindow,
       
  1167             KHeartbeatIntervalWindow ) )
       
  1168         {
       
  1169         aResult.SetResult( 
       
  1170             KErrGeneral, 
       
  1171             _L("Test case failed. Heartbeat failure.") );
       
  1172         }
       
  1173 
       
  1174     // Clean up
       
  1175     timestamps.Close();
       
  1176     secondTimestamps.Close();
       
  1177     timer->Cancel();
       
  1178     CleanupStack::PopAndDestroy( timer );
       
  1179 
       
  1180     heartbeatTimes.Close();
       
  1181     heartbeat->Cancel();
       
  1182     CleanupStack::PopAndDestroy( heartbeat );
       
  1183 
       
  1184     __UHEAP_MARKEND;
       
  1185 
       
  1186     return KErrNone;
       
  1187     }
       
  1188 
       
  1189 
       
  1190 // ---------------------------------------------------------------------------
       
  1191 // TEST CASE: Start a running timer again.
       
  1192 // ---------------------------------------------------------------------------
       
  1193 //
       
  1194 TInt CTestFlexPeriodic::StartAfterStartL(
       
  1195     TTestResult& aResult, 
       
  1196     CTestFlexTimer* aCallback  )
       
  1197     {
       
  1198     __UHEAP_MARK;
       
  1199 
       
  1200     // Constants
       
  1201     const TTimeIntervalMicroSeconds32 KTimerDelay( 2000000 );
       
  1202     const TTimeIntervalMicroSeconds32 KTimerInterval( 2000000 );
       
  1203 
       
  1204     // Default result if anything leaves i.e. no analyze done.
       
  1205     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1206 
       
  1207     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
  1208     CleanupStack::PushL( timer );
       
  1209 
       
  1210     // This start should work...
       
  1211     timer->Start( 
       
  1212         KTimerDelay, 
       
  1213         KTimerInterval, 
       
  1214         TCallBack( DoNothing, NULL ) );
       
  1215 
       
  1216     // ... and next start should panic with
       
  1217     // Panic category: "E32USER-CBase"
       
  1218     // Panic reason:   42 (attempt to active CActive when a request is still 
       
  1219     //                     outstanding)
       
  1220     
       
  1221     // Set panic code 42 to acceptable exit reason
       
  1222     aCallback->TestModuleIf().SetExitReason( 
       
  1223         CTestModuleIf::EPanic,
       
  1224         42 );
       
  1225 
       
  1226     timer->Start( 
       
  1227         KTimerDelay, 
       
  1228         KTimerInterval, 
       
  1229         TCallBack( DoNothing, NULL ) );
       
  1230 
       
  1231     // No panic, change result back to normal
       
  1232     aCallback->TestModuleIf().SetExitReason( 
       
  1233         CTestModuleIf::ENormal,
       
  1234         KErrNone );
       
  1235 
       
  1236     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1237 
       
  1238     // Clean up
       
  1239     timer->Cancel();
       
  1240     CleanupStack::PopAndDestroy( timer );
       
  1241 
       
  1242     __UHEAP_MARKEND;    
       
  1243 
       
  1244     return KErrNone;
       
  1245     }
       
  1246 
       
  1247 // ---------------------------------------------------------------------------
       
  1248 // TEST CASE: Start a running timer again in callback function
       
  1249 // ---------------------------------------------------------------------------
       
  1250 //
       
  1251 TInt CTestFlexPeriodic::StartInCallbackL(
       
  1252     TTestResult& aResult, 
       
  1253     CTestFlexTimer* aCallback  )
       
  1254     {
       
  1255     __UHEAP_MARK;
       
  1256 
       
  1257     // Constants
       
  1258     const TTimeIntervalMicroSeconds32 KTimerDelay( 1000000 );
       
  1259     const TTimeIntervalMicroSeconds32 KTimerInterval( 1000000 );
       
  1260     const TTimeIntervalMicroSeconds32 KTestRunTime( 3000000 );
       
  1261     
       
  1262     // Default result if anything leaves i.e. no analyze done.
       
  1263     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1264 
       
  1265     CFlexPeriodic* timer = CFlexPeriodic::NewL( CActive::EPriorityStandard );
       
  1266     CleanupStack::PushL( timer );
       
  1267 
       
  1268     // The callback should panic with
       
  1269     // Panic category: "E32USER-CBase"
       
  1270     // Panic reason:   42 (attempt to active CActive when a request is still 
       
  1271     //                     outstanding)
       
  1272     
       
  1273     // Set panic code 42 to acceptable exit reason
       
  1274     aCallback->TestModuleIf().SetExitReason( 
       
  1275         CTestModuleIf::EPanic,
       
  1276         42 );
       
  1277 
       
  1278     timer->Start( 
       
  1279         KTimerDelay, 
       
  1280         KTimerInterval, 
       
  1281         TCallBack( StartTimer, timer ) );
       
  1282 
       
  1283                             //    //  ___     _____
       
  1284     WaitL( KTestRunTime ); // // // //_ // //  //
       
  1285                           //_//_// //  // //  //
       
  1286 
       
  1287     // No panic, change result back to normal
       
  1288     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1289 
       
  1290     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1291 
       
  1292     // Clean up
       
  1293     timer->Cancel();
       
  1294     CleanupStack::PopAndDestroy( timer );
       
  1295 
       
  1296     __UHEAP_MARKEND;    
       
  1297 
       
  1298     return KErrNone;
       
  1299     }
       
  1300 
       
  1301 // ---------------------------------------------------------------------------
       
  1302 // TEST CASE: Start with negative delay, 32 bit interface
       
  1303 // ---------------------------------------------------------------------------
       
  1304 //
       
  1305 TInt CTestFlexPeriodic::StartWithNegativeDelay32L(
       
  1306     TTestResult& aResult, 
       
  1307     CTestFlexTimer* aCallback  )
       
  1308     {
       
  1309     __UHEAP_MARK;
       
  1310 
       
  1311     const TInt KAllowedValue( 1 );
       
  1312     const TInt KIllegalValue( -1 );
       
  1313 
       
  1314     RArray<TTime> timestamps;
       
  1315 
       
  1316     // Default result if anything leaves i.e. no analyze done.
       
  1317     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1318 
       
  1319     // ConfigureAndStartTimerL should panic:
       
  1320     //  Category: "CFlexPeriodic" 
       
  1321     //  Reason:   6 (EFlexPeriodicDelayLessThanZero)
       
  1322     // Set the panic code to acceptable exit reason
       
  1323     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 6 );
       
  1324 
       
  1325     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1326         timestamps,
       
  1327         KIllegalValue,
       
  1328         KAllowedValue,
       
  1329         KAllowedValue,
       
  1330         KAllowedValue );
       
  1331 
       
  1332     // No panic, change result back to normal
       
  1333     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1334     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1335     
       
  1336     // Clean up
       
  1337     timestamps.Close();
       
  1338     
       
  1339     __UHEAP_MARKEND;
       
  1340 
       
  1341     return KErrNone;
       
  1342     }
       
  1343 
       
  1344 // ---------------------------------------------------------------------------
       
  1345 // TEST CASE: Start with zero interval, 32 bit interface
       
  1346 // ---------------------------------------------------------------------------
       
  1347 //
       
  1348 TInt CTestFlexPeriodic::StartWithZeroInterval32L(
       
  1349     TTestResult& aResult, 
       
  1350     CTestFlexTimer* aCallback  )
       
  1351     {
       
  1352     __UHEAP_MARK;
       
  1353 
       
  1354     const TInt KAllowedValue( 1 );
       
  1355     const TInt KIllegalValue( 0 );
       
  1356 
       
  1357     RArray<TTime> timestamps;
       
  1358 
       
  1359     // Default result if anything leaves i.e. no analyze done.
       
  1360     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1361 
       
  1362     // ConfigureAndStartTimerL should panic:
       
  1363     //  Category: "CFlexPeriodic" 
       
  1364     //  Reason:   7 (EFlexPeriodicIntervalTooSmall)
       
  1365     // Set the panic code to acceptable exit reason
       
  1366     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
       
  1367 
       
  1368     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1369         timestamps,
       
  1370         KAllowedValue,
       
  1371         KIllegalValue,
       
  1372         KAllowedValue,
       
  1373         KAllowedValue );
       
  1374 
       
  1375     // No panic, change result back to normal
       
  1376     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1377     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1378     
       
  1379     // Clean up
       
  1380     timestamps.Close();
       
  1381 
       
  1382     __UHEAP_MARKEND;
       
  1383 
       
  1384     return KErrNone;
       
  1385     }
       
  1386 
       
  1387 // ---------------------------------------------------------------------------
       
  1388 // TEST CASE: Start with negative interval, 32 bit interface
       
  1389 // ---------------------------------------------------------------------------
       
  1390 //
       
  1391 TInt CTestFlexPeriodic::StartWithNegativeInterval32L(
       
  1392     TTestResult& aResult, 
       
  1393     CTestFlexTimer* aCallback  )
       
  1394     {
       
  1395     __UHEAP_MARK;
       
  1396 
       
  1397     const TInt KAllowedValue( 1 );
       
  1398     const TInt KIllegalValue( -1 );
       
  1399 
       
  1400     RArray<TTime> timestamps;
       
  1401 
       
  1402     // Default result if anything leaves i.e. no analyze done.
       
  1403     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1404 
       
  1405     // ConfigureAndStartTimerL should panic:
       
  1406     //  Category: "CFlexPeriodic" 
       
  1407     //  Reason:   7 (EFlexPeriodicIntervalTooSmall)
       
  1408     // Set the panic code to acceptable exit reason
       
  1409     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
       
  1410 
       
  1411     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1412         timestamps,
       
  1413         KAllowedValue,
       
  1414         KIllegalValue,
       
  1415         KAllowedValue,
       
  1416         KAllowedValue );
       
  1417 
       
  1418     // No panic, change result back to normal
       
  1419     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1420     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1421     
       
  1422     // Clean up
       
  1423     timestamps.Close();
       
  1424 
       
  1425     __UHEAP_MARKEND;
       
  1426 
       
  1427     return KErrNone;
       
  1428     }
       
  1429 
       
  1430 // ---------------------------------------------------------------------------
       
  1431 // TEST CASE: Start with negative delay, 64 bit interface
       
  1432 // ---------------------------------------------------------------------------
       
  1433 //
       
  1434 TInt CTestFlexPeriodic::StartWithNegativeDelay64L(
       
  1435     TTestResult& aResult, 
       
  1436     CTestFlexTimer* aCallback  )
       
  1437     {
       
  1438     __UHEAP_MARK;
       
  1439 
       
  1440     const TInt KAllowedValue( 1 );
       
  1441     const TInt KIllegalValue( -1 );
       
  1442 
       
  1443     RArray<TTime> timestamps;
       
  1444     
       
  1445     // Default result if anything leaves i.e. no analyze done.
       
  1446     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1447 
       
  1448     // ConfigureAndStartTimerL should panic:
       
  1449     //  Category: "CFlexPeriodic" 
       
  1450     //  Reason:   6 (EFlexPeriodicDelayLessThanZero)
       
  1451     // Set the panic code to acceptable exit reason
       
  1452     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 6 );
       
  1453 
       
  1454     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1455         timestamps,
       
  1456         KIllegalValue,
       
  1457         KAllowedValue,
       
  1458         KAllowedValue,
       
  1459         KAllowedValue );
       
  1460 
       
  1461     // No panic, change result back to normal
       
  1462     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1463     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1464     
       
  1465     // Clean up
       
  1466     timestamps.Close();
       
  1467 
       
  1468     __UHEAP_MARKEND;
       
  1469 
       
  1470     return KErrNone;
       
  1471     }
       
  1472 
       
  1473 // ---------------------------------------------------------------------------
       
  1474 // TEST CASE: Start with zero interval, 64 bit interface
       
  1475 // ---------------------------------------------------------------------------
       
  1476 //
       
  1477 TInt CTestFlexPeriodic::StartWithZeroInterval64L(
       
  1478     TTestResult& aResult, 
       
  1479     CTestFlexTimer* aCallback  )
       
  1480     {
       
  1481     __UHEAP_MARK;
       
  1482 
       
  1483     const TInt KAllowedValue( 1 );
       
  1484     const TInt KIllegalValue( 0 );
       
  1485     
       
  1486     RArray<TTime> timestamps;
       
  1487     
       
  1488     // Default result if anything leaves i.e. no analyze done.
       
  1489     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1490 
       
  1491     // ConfigureAndStartTimerL should panic:
       
  1492     //  Category: "CFlexPeriodic" 
       
  1493     //  Reason:   7 (EFlexPeriodicIntervalTooSmall)
       
  1494     // Set the panic code to acceptable exit reason
       
  1495     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
       
  1496 
       
  1497     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1498         timestamps,
       
  1499         KAllowedValue,
       
  1500         KIllegalValue,
       
  1501         KAllowedValue,
       
  1502         KAllowedValue );
       
  1503 
       
  1504     // No panic, change result back to normal
       
  1505     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1506     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1507     
       
  1508     // Clean up
       
  1509     timestamps.Close();
       
  1510 
       
  1511     __UHEAP_MARKEND;
       
  1512 
       
  1513     return KErrNone;
       
  1514     }
       
  1515 
       
  1516 // ---------------------------------------------------------------------------
       
  1517 // TEST CASE: Start with negative interval, 64 bit interface
       
  1518 // ---------------------------------------------------------------------------
       
  1519 //
       
  1520 TInt CTestFlexPeriodic::StartWithNegativeInterval64L(
       
  1521     TTestResult& aResult, 
       
  1522     CTestFlexTimer* aCallback  )
       
  1523     {
       
  1524     __UHEAP_MARK;
       
  1525 
       
  1526     const TInt KAllowedValue( 1 );
       
  1527     const TInt KIllegalValue( -1 );
       
  1528     
       
  1529     RArray<TTime> timestamps;
       
  1530     
       
  1531     // Default result if anything leaves i.e. no analyze done.
       
  1532     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1533 
       
  1534     // ConfigureAndStartTimerL should panic:
       
  1535     //  Category: "CFlexPeriodic" 
       
  1536     //  Reason:   7 (EFlexPeriodicIntervalTooSmall)
       
  1537     // Set the panic code to acceptable exit reason
       
  1538     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 7 );
       
  1539 
       
  1540     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1541         timestamps,
       
  1542         KAllowedValue,
       
  1543         KIllegalValue,
       
  1544         KAllowedValue,
       
  1545         KAllowedValue );
       
  1546 
       
  1547     // No panic, change result back to normal
       
  1548     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1549     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1550     
       
  1551     // Clean up
       
  1552     timestamps.Close();
       
  1553 
       
  1554     __UHEAP_MARKEND;
       
  1555 
       
  1556     return KErrNone;
       
  1557     }
       
  1558 
       
  1559 // ---------------------------------------------------------------------------
       
  1560 // TEST CASE: Configure timer with negative delay window, 32 bit interface
       
  1561 // ---------------------------------------------------------------------------
       
  1562 //
       
  1563 TInt CTestFlexPeriodic::ConfigureWithNegativeDelayWindow32L(
       
  1564     TTestResult& aResult, 
       
  1565     CTestFlexTimer* aCallback  )
       
  1566     {
       
  1567     __UHEAP_MARK;
       
  1568 
       
  1569     const TInt KAllowedValue( 1 );
       
  1570     const TInt KIllegalValue( -1 );
       
  1571     
       
  1572     RArray<TTime> timestamps;
       
  1573     
       
  1574     // Default result if anything leaves i.e. no analyze done.
       
  1575     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1576 
       
  1577     // ConfigureAndStartTimerL should panic:
       
  1578     //  Category: "CFlexPeriodic" 
       
  1579     //  Reason:   8 (EFlexPeriodicDelayWindowLessThanZero)
       
  1580     // Set the panic code to acceptable exit reason
       
  1581     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 8 );
       
  1582 
       
  1583     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1584         timestamps,
       
  1585         KAllowedValue,
       
  1586         KAllowedValue,
       
  1587         KIllegalValue,
       
  1588         KAllowedValue );
       
  1589 
       
  1590     // No panic, change result back to normal
       
  1591     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1592     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1593     
       
  1594     // Clean up
       
  1595     timestamps.Close();
       
  1596 
       
  1597     __UHEAP_MARKEND;
       
  1598 
       
  1599     return KErrNone;
       
  1600     }
       
  1601 
       
  1602 // ---------------------------------------------------------------------------
       
  1603 // TEST CASE: Configure timer with negative interval window, 32 bit interface
       
  1604 // ---------------------------------------------------------------------------
       
  1605 //
       
  1606 TInt CTestFlexPeriodic::ConfigureWithNegativeIntervalWindow32L(
       
  1607     TTestResult& aResult, 
       
  1608     CTestFlexTimer* aCallback  )
       
  1609     {
       
  1610     __UHEAP_MARK;
       
  1611 
       
  1612     const TInt KAllowedValue( 1 );
       
  1613     const TInt KIllegalValue( -1 );
       
  1614     
       
  1615     RArray<TTime> timestamps;
       
  1616     
       
  1617     // Default result if anything leaves i.e. no analyze done.
       
  1618     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1619 
       
  1620     // ConfigureAndStartTimerL should panic:
       
  1621     //  Category: "CFlexPeriodic" 
       
  1622     //  Reason:   9 (EFlexPeriodicIntervalWindowLessThanZero)
       
  1623     // Set the panic code to acceptable exit reason
       
  1624     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 9 );
       
  1625 
       
  1626     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1627         timestamps,
       
  1628         KAllowedValue,
       
  1629         KAllowedValue,
       
  1630         KAllowedValue,
       
  1631         KIllegalValue );
       
  1632 
       
  1633     // No panic, change result back to normal
       
  1634     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1635     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1636     
       
  1637     // Clean up
       
  1638     timestamps.Close();
       
  1639 
       
  1640     __UHEAP_MARKEND;
       
  1641 
       
  1642     return KErrNone;
       
  1643     }
       
  1644 
       
  1645 // ---------------------------------------------------------------------------
       
  1646 // TEST CASE: Configure timer with negative delay window, 64 bit interface
       
  1647 // ---------------------------------------------------------------------------
       
  1648 //
       
  1649 TInt CTestFlexPeriodic::ConfigureWithNegativeDelayWindow64L(
       
  1650     TTestResult& aResult, 
       
  1651     CTestFlexTimer* aCallback  )
       
  1652     {
       
  1653     __UHEAP_MARK;
       
  1654 
       
  1655     const TInt KAllowedValue( 1 );
       
  1656     const TInt KIllegalValue( -1 );
       
  1657     
       
  1658     RArray<TTime> timestamps;
       
  1659     
       
  1660     // Default result if anything leaves i.e. no analyze done.
       
  1661     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1662 
       
  1663     // ConfigureAndStartTimerL should panic:
       
  1664     //  Category: "CFlexPeriodic" 
       
  1665     //  Reason:   8 (EFlexPeriodicDelayWindowLessThanZero)
       
  1666     // Set the panic code to acceptable exit reason
       
  1667     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 8 );
       
  1668 
       
  1669     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1670         timestamps,
       
  1671         KAllowedValue,
       
  1672         KAllowedValue,
       
  1673         KIllegalValue,
       
  1674         KAllowedValue );
       
  1675 
       
  1676     // No panic, change result back to normal
       
  1677     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1678     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1679     
       
  1680     // Clean up
       
  1681     timestamps.Close();
       
  1682 
       
  1683     __UHEAP_MARKEND;
       
  1684 
       
  1685     return KErrNone;
       
  1686     }
       
  1687 
       
  1688 // ---------------------------------------------------------------------------
       
  1689 // TEST CASE: Configure timer with negative interval window, 64 bit interface
       
  1690 // ---------------------------------------------------------------------------
       
  1691 //
       
  1692 TInt CTestFlexPeriodic::ConfigureWithNegativeIntervalWindow64L(
       
  1693     TTestResult& aResult, 
       
  1694     CTestFlexTimer* aCallback  )
       
  1695     {
       
  1696     __UHEAP_MARK;
       
  1697 
       
  1698     const TInt KAllowedValue( 1 );
       
  1699     const TInt KIllegalValue( -1 );
       
  1700     
       
  1701     RArray<TTime> timestamps;
       
  1702     
       
  1703     // Default result if anything leaves i.e. no analyze done.
       
  1704     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1705 
       
  1706     // ConfigureAndStartTimerL should panic:
       
  1707     //  Category: "CFlexPeriodic" 
       
  1708     //  Reason:   9 (EFlexPeriodicIntervalWindowLessThanZero)
       
  1709     // Set the panic code to acceptable exit reason
       
  1710     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 9 );
       
  1711 
       
  1712     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1713         timestamps,
       
  1714         KAllowedValue,
       
  1715         KAllowedValue,
       
  1716         KAllowedValue,
       
  1717         KIllegalValue );
       
  1718 
       
  1719     // No panic, change result back to normal
       
  1720     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1721     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1722     
       
  1723     // Clean up
       
  1724     timestamps.Close();
       
  1725 
       
  1726     __UHEAP_MARKEND;
       
  1727 
       
  1728     return KErrNone;
       
  1729     }
       
  1730 
       
  1731 // ---------------------------------------------------------------------------
       
  1732 // TEST CASE: Start with minimum and maximum values
       
  1733 // ---------------------------------------------------------------------------
       
  1734 //
       
  1735 TInt CTestFlexPeriodic::StartWithMinAndMaxL(
       
  1736     TTestResult& aResult, 
       
  1737     CTestFlexTimer* /* aCallback */  )
       
  1738     {
       
  1739     __UHEAP_MARK;
       
  1740 
       
  1741     const TInt KMinimumDelayValue( 0 );
       
  1742     const TInt KMinimumIntervalValue( 1 );
       
  1743     const TInt KNormalValue( 1000000 );
       
  1744     const TInt KMaximum32BitValue( 0x7FFFFFFF );
       
  1745 
       
  1746 //    const TInt64 KLarge64BitValue( 0x6FFFFFFFFFFFFFFF );  // Should not panic (till few years)
       
  1747 
       
  1748     // Years * Days * Hours * Minutes * Seconds * Microseconds
       
  1749     const TInt64 KLarge64BitValue( ((TInt64)(1)) * 365 * 24 * 60 * 60 * 1000000 );
       
  1750     
       
  1751     // Default result if anything leaves i.e. no analyze done.
       
  1752     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1753     
       
  1754     RArray<TTime> timestamps;
       
  1755 
       
  1756     TTime now;
       
  1757     now.UniversalTime();
       
  1758 
       
  1759     // > DEBUG
       
  1760     TTimeIntervalMicroSeconds longLongInterval( KLarge64BitValue );
       
  1761     now += longLongInterval;
       
  1762     TDateTime date;
       
  1763     date = now.DateTime();
       
  1764     // < DEBUG
       
  1765 
       
  1766     // Start with min delay, 32 bit
       
  1767     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1768         timestamps,
       
  1769         KMinimumDelayValue,
       
  1770         KNormalValue,
       
  1771         KNormalValue,
       
  1772         KNormalValue );
       
  1773     // Validate results
       
  1774     if ( !AreTimestampsAtWindow(
       
  1775             timestamps,
       
  1776             TTimeIntervalMicroSeconds32( KMinimumDelayValue ),
       
  1777             TTimeIntervalMicroSeconds32( KNormalValue ),
       
  1778             TTimeIntervalMicroSeconds32( KNormalValue ),
       
  1779             TTimeIntervalMicroSeconds32( KNormalValue ) ) )
       
  1780         {
       
  1781         aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit min delay failed") );
       
  1782         }
       
  1783     timestamps.Reset();
       
  1784 
       
  1785     // Start with max delay, 32 bit
       
  1786     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1787         timestamps,
       
  1788         KMaximum32BitValue,
       
  1789         KNormalValue,
       
  1790         KNormalValue,
       
  1791         KNormalValue );
       
  1792     // Validate results
       
  1793     // Only one timestamp (the start time) is allowed
       
  1794     if ( timestamps.Count() > 1 )
       
  1795         {
       
  1796         aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit max delay failed") );
       
  1797         }
       
  1798     timestamps.Reset();
       
  1799 
       
  1800     // Start with min interval, 32 bit
       
  1801     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1802         timestamps,
       
  1803         KNormalValue,
       
  1804         KMinimumIntervalValue,
       
  1805         KNormalValue,
       
  1806         KNormalValue );
       
  1807     // Validate results
       
  1808     if ( !AreTimestampsAtWindow(
       
  1809             timestamps,
       
  1810             TTimeIntervalMicroSeconds32( KNormalValue ),
       
  1811             TTimeIntervalMicroSeconds32( KMinimumIntervalValue ),
       
  1812             TTimeIntervalMicroSeconds32( KNormalValue ),
       
  1813             TTimeIntervalMicroSeconds32( KNormalValue ) ) )
       
  1814         {
       
  1815         aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit min interval failed") );
       
  1816         }
       
  1817     timestamps.Reset();
       
  1818 
       
  1819     // Start with max interval, 32 bit
       
  1820     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds32, TTimeIntervalMicroSeconds32>(
       
  1821         timestamps,
       
  1822         KNormalValue,
       
  1823         KMaximum32BitValue,
       
  1824         KNormalValue,
       
  1825         KNormalValue );
       
  1826     // Validate results
       
  1827     if ( !AreTimestampsAtWindow(
       
  1828             timestamps,
       
  1829             TTimeIntervalMicroSeconds32( KNormalValue ),
       
  1830             TTimeIntervalMicroSeconds32( KMaximum32BitValue ),
       
  1831             TTimeIntervalMicroSeconds32( KNormalValue ),
       
  1832             TTimeIntervalMicroSeconds32( KNormalValue ) ) )
       
  1833         {
       
  1834         aResult.SetResult( KErrGeneral, _L("Test case failed. 32 bit min interval failed") );
       
  1835         }
       
  1836     timestamps.Reset();
       
  1837 
       
  1838     // Start with min delay, 64 bit
       
  1839     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1840         timestamps,
       
  1841         KMinimumDelayValue,
       
  1842         KNormalValue,
       
  1843         KNormalValue,
       
  1844         KNormalValue );
       
  1845     // Validate results
       
  1846     if ( !AreTimestampsAtWindow(
       
  1847             timestamps,
       
  1848             TTimeIntervalMicroSeconds( KMinimumDelayValue ),
       
  1849             TTimeIntervalMicroSeconds( KNormalValue ),
       
  1850             TTimeIntervalMicroSeconds( KNormalValue ),
       
  1851             TTimeIntervalMicroSeconds( KNormalValue ) ) )
       
  1852         {
       
  1853         aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit min delay failed") );
       
  1854         }
       
  1855     timestamps.Reset();
       
  1856 
       
  1857     // Start with large delay, 64 bit
       
  1858     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1859         timestamps,
       
  1860         KLarge64BitValue,
       
  1861         KNormalValue,
       
  1862         KNormalValue,
       
  1863         KNormalValue );
       
  1864     // Validate results
       
  1865     // Only one timestamp (the start time) is allowed
       
  1866     if ( timestamps.Count() > 1 )
       
  1867         {
       
  1868         aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit max delay failed") );
       
  1869         }
       
  1870     timestamps.Reset();
       
  1871 
       
  1872     // Start with min interval, 64 bit
       
  1873     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1874         timestamps,
       
  1875         KNormalValue,
       
  1876         KMinimumIntervalValue,
       
  1877         KNormalValue,
       
  1878         KNormalValue );
       
  1879     // Validate results
       
  1880     if ( !AreTimestampsAtWindow(
       
  1881             timestamps,
       
  1882             TTimeIntervalMicroSeconds( KNormalValue ),
       
  1883             TTimeIntervalMicroSeconds( KMinimumIntervalValue ),
       
  1884             TTimeIntervalMicroSeconds( KNormalValue ),
       
  1885             TTimeIntervalMicroSeconds( KNormalValue ) ) )
       
  1886         {
       
  1887         aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit min interval failed") );
       
  1888         }
       
  1889     timestamps.Reset();
       
  1890 
       
  1891     // Start with large interval, 64 bit
       
  1892     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1893         timestamps,
       
  1894         KNormalValue,
       
  1895         KLarge64BitValue,
       
  1896         KNormalValue,
       
  1897         KNormalValue );
       
  1898     // Validate results
       
  1899     // AreTimestampsAtWindow() does not accept values over 0xFFFFFFFF.
       
  1900     // However, this is not a problem due there should be only the timestamps
       
  1901     // of start time and delay expiration; 32 bit value can be used instead of
       
  1902     // the real interval.
       
  1903     if ( !AreTimestampsAtWindow(
       
  1904             timestamps,
       
  1905             TTimeIntervalMicroSeconds( KNormalValue ),
       
  1906             TTimeIntervalMicroSeconds( KMaximum32BitValue ),
       
  1907             TTimeIntervalMicroSeconds( KNormalValue ),
       
  1908             TTimeIntervalMicroSeconds( KNormalValue ) ) )
       
  1909         {
       
  1910         aResult.SetResult( KErrGeneral, _L("Test case failed. 64 bit max interval failed") );
       
  1911         }
       
  1912     timestamps.Reset();
       
  1913 
       
  1914     // If test execution is here, we'll passed
       
  1915     aResult.SetResult( KErrNone, _L("Test case passed") );
       
  1916 
       
  1917     // Clean up
       
  1918     timestamps.Close();
       
  1919     __UHEAP_MARKEND;
       
  1920 
       
  1921     return KErrNone;
       
  1922     }
       
  1923 
       
  1924 
       
  1925 // ---------------------------------------------------------------------------
       
  1926 // TEST CASE: Start timer with maximum delay, 64 bit interface
       
  1927 // ---------------------------------------------------------------------------
       
  1928 //
       
  1929 TInt CTestFlexPeriodic::StartWithMaximumDelay64L(
       
  1930     TTestResult& aResult, 
       
  1931     CTestFlexTimer* aCallback  )
       
  1932     {
       
  1933     __UHEAP_MARK;
       
  1934 
       
  1935     const TInt KAllowedValue( 1 );
       
  1936     const TInt64 KIllegalValue( 0x7FFFFFFFFFFFFFFF );
       
  1937     
       
  1938     RArray<TTime> timestamps;
       
  1939     
       
  1940     // Default result if anything leaves i.e. no analyze done.
       
  1941     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1942 
       
  1943     // ConfigureAndStartTimerL should panic:
       
  1944     //  Category: "CFlexPeriodic" 
       
  1945     //  Reason:   24 (EFlexTimerServerIllegalTimerValue)
       
  1946     // Set the panic code to acceptable exit reason
       
  1947     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 24 );
       
  1948 
       
  1949     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1950         timestamps,
       
  1951         KIllegalValue,
       
  1952         KAllowedValue,
       
  1953         KAllowedValue,
       
  1954         KAllowedValue );
       
  1955 
       
  1956     // No panic, change result back to normal
       
  1957     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  1958     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  1959     
       
  1960     // Clean up
       
  1961     timestamps.Close();
       
  1962 
       
  1963     __UHEAP_MARKEND;
       
  1964 
       
  1965     return KErrNone;
       
  1966     }
       
  1967 
       
  1968 // ---------------------------------------------------------------------------
       
  1969 // TEST CASE: Start timer with maximum interval, 64 bit interface
       
  1970 // ---------------------------------------------------------------------------
       
  1971 //
       
  1972 TInt CTestFlexPeriodic::StartWithMaximumInterval64L(
       
  1973     TTestResult& aResult, 
       
  1974     CTestFlexTimer* aCallback  )
       
  1975     {
       
  1976     __UHEAP_MARK;
       
  1977 
       
  1978     const TInt KAllowedValue( 1 );
       
  1979     const TInt64 KIllegalValue( 0x7FFFFFFFFFFFFFFF );
       
  1980     
       
  1981     RArray<TTime> timestamps;
       
  1982     
       
  1983     // Default result if anything leaves i.e. no analyze done.
       
  1984     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  1985 
       
  1986     // ConfigureAndStartTimerL should panic:
       
  1987     //  Category: "CFlexPeriodic" 
       
  1988     //  Reason:   24 (EFlexTimerServerIllegalTimerValue)
       
  1989     // Set the panic code to acceptable exit reason
       
  1990     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::EPanic, 24 );
       
  1991 
       
  1992     ConfigureAndStartTimerL<TTimeIntervalMicroSeconds, TTimeIntervalMicroSeconds>(
       
  1993         timestamps,
       
  1994         KAllowedValue,
       
  1995         KIllegalValue,
       
  1996         KAllowedValue,
       
  1997         KAllowedValue );
       
  1998 
       
  1999     // No panic, change result back to normal
       
  2000     aCallback->TestModuleIf().SetExitReason( CTestModuleIf::ENormal, KErrNone );
       
  2001     aResult.SetResult( KErrGeneral, _L("Test case failed. No panic.") );
       
  2002     
       
  2003     // Clean up
       
  2004     timestamps.Close();
       
  2005 
       
  2006     __UHEAP_MARKEND;
       
  2007 
       
  2008     return KErrNone;
       
  2009     }
       
  2010 
       
  2011 // ---------------------------------------------------------------------------
       
  2012 // TEST CASE: Start timer with NULL callback (32 bit)
       
  2013 // ---------------------------------------------------------------------------
       
  2014 //
       
  2015 TInt CTestFlexPeriodic::StartWithNullCallBack32L(
       
  2016     TTestResult& aResult, 
       
  2017     CTestFlexTimer* aCallback )
       
  2018     {
       
  2019     return StartWithNullCallBackL<TTimeIntervalMicroSeconds32>( aResult, aCallback );
       
  2020     }
       
  2021 
       
  2022 // ---------------------------------------------------------------------------
       
  2023 // TEST CASE: Start timer with NULL callback (64 bit)
       
  2024 // ---------------------------------------------------------------------------
       
  2025 //
       
  2026 TInt CTestFlexPeriodic::StartWithNullCallBack64L(
       
  2027     TTestResult& aResult, 
       
  2028     CTestFlexTimer* aCallback )
       
  2029     {
       
  2030     return StartWithNullCallBackL<TTimeIntervalMicroSeconds>( aResult, aCallback );
       
  2031     }
       
  2032 
       
  2033 // ---------------------------------------------------------------------------
       
  2034 // TEST CASE: Client crashes
       
  2035 // 1) Start two timers in separate threads
       
  2036 // 2) The 1st timer will panic after a while
       
  2037 // 3) Check that the 2nd timer is ok -> server works OK
       
  2038 // ---------------------------------------------------------------------------
       
  2039 //
       
  2040 TInt CTestFlexPeriodic::ClientCrashL(
       
  2041     TTestResult& aResult, 
       
  2042     CTestFlexTimer* aCallback )
       
  2043     {
       
  2044     __UHEAP_MARK;
       
  2045 
       
  2046     // Must be bigger than ClientCrashL and StartOneTimerL
       
  2047     const TTimeIntervalMicroSeconds32 KTestRunTime( 6000000 );
       
  2048 
       
  2049     // Default result if anything leaves i.e. no analyze done.
       
  2050     aResult.SetResult( KErrGeneral, _L("Test case leaved") );
       
  2051     
       
  2052     // Start test case ClientCrashL
       
  2053     RThread threadA;
       
  2054     TTestResult resultA;
       
  2055     TTestCaseArguments caseA = { DoPanicL, resultA, aCallback }; 
       
  2056     RunInThread( threadA, caseA );
       
  2057 
       
  2058     // Start test case StartOneTimerL
       
  2059     RThread threadB;
       
  2060     TTestResult resultB;
       
  2061     TTestCaseArguments caseB = { StartOneTimerL, resultB, aCallback }; 
       
  2062     RunInThread( threadB, caseB );
       
  2063 
       
  2064                             //    //  ___     _____
       
  2065     WaitL( KTestRunTime ); // // // //_ // //  //
       
  2066                           //_//_// //  // //  //
       
  2067 
       
  2068     // Analyze results
       
  2069     aResult.SetResult(KErrNone, _L("Test case passed.") );
       
  2070 
       
  2071     // ClientCrashL should be paniced with reason 0xDEAD
       
  2072     if ( threadA.ExitType() != EExitPanic || threadA.ExitReason() != 0xDEAD )
       
  2073         {
       
  2074         aResult.SetResult( 
       
  2075             KErrGeneral, 
       
  2076             _L("Test case failed. Client did not panic (correctly).") );
       
  2077         }
       
  2078     // StartOneTimerL should be finished ok
       
  2079     else if ( resultB.iResult != KErrNone || threadB.ExitType() == EExitPanic )
       
  2080         {
       
  2081         aResult.SetResult( 
       
  2082             KErrGeneral, 
       
  2083             _L("Test case failed. Timer failed.") );
       
  2084         }
       
  2085 
       
  2086     threadA.Close();
       
  2087     threadB.Close();
       
  2088     __UHEAP_MARKEND;
       
  2089 
       
  2090     return KErrNone;
       
  2091     }