windows-nt/Source/XPSP1/NT/com/svcdlls/trksvcs/utest/ttimer.hxx
2020-09-26 16:20:57 +08:00

703 lines
13 KiB
C++

#ifndef _TTIMER_HXX_
#define _TTIMER_HXX_
template < class TEnum > TEnum operator ++ ( TEnum &sub_phase, int )
{
TEnum old = sub_phase;
sub_phase = static_cast<TEnum>( static_cast<int>(sub_phase) + 1 );
return( old );
}
class CTimerTest : public PTimerCallback
{
public:
CTimerTest()
{
_fInitialized = FALSE;
_cftExpected = 0;
_hEvent = NULL;
_ptszName = NULL;
}
virtual ~CTimerTest()
{
UnInitialize();
}
public:
void Initialize(PTimerCallback *pTimerCallback,
const TCHAR *ptszName,
ULONG ulTimerContext,
ULONG ulPeriodInSeconds,
CNewTimer::TimerRetryType retrytype,
ULONG ulLowerRetryTime,
ULONG ulUpperRetryTime,
ULONG ulMaxLifetime );
void UnInitialize()
{
if( _fInitialized )
{
_timer.Cancel();
_timer.UnInitialize();
_fInitialized = FALSE;
}
}
public:
void WaitForTestToComplete()
{
if( 0xffffffff == WaitForSingleObjectEx( _hEvent, INFINITE, FALSE ))
{
TrkLog(( TRKDBG_ERROR, TEXT("Couldn't wait for event")));
TrkRaiseLastError( );
}
}
void MarkTestCompleted()
{
if( !SetEvent( _hEvent ))
TrkRaiseLastError( );
}
void EnsureTimerIsStopped( )
{
_tprintf( TEXT(" Verifying that timer is stopped (%ds)\n"),
g_ulDefaultPeriod * 2 );
VerifyRegistryDataRemoved();
Sleep( g_ulDefaultPeriod * 2 * 1000 );
}
void SetTimerRegistryValue( const TCHAR *ptszName,
const CFILETIME &cftSet, const CFILETIME cftDue,
ULONG ulRetry );
void VerifyRegistryDataCorrect();
void VerifyRegistryDataRemoved();
public:
void SetSingleShot( const CFILETIME &cftExpected = 0 )
{
if( 0 != cftExpected )
_cftExpected = cftExpected;
else
{
_cftExpected = CFILETIME();
_cftExpected.IncrementSeconds( _ulPeriod );
}
_timer.SetSingleShot();
TrkLog(( TRKDBG_TIMER, TEXT("%s"), CDebugString( _timer )._tsz ));
if( _ptszName )
VerifyRegistryDataCorrect();
}
void SetRecurring( const CFILETIME &cftExpected = 0 )
{
if( 0 != cftExpected )
_cftExpected = cftExpected;
else
{
_cftExpected = CFILETIME();
_cftExpected.IncrementSeconds( _ulPeriod );
}
_timer.SetRecurring();
if( _ptszName )
VerifyRegistryDataCorrect();
}
protected:
BOOL _fInitialized;
CNewTimer _timer;
ULONG _ulPeriod;
const TCHAR * _ptszName;
CFILETIME _cftExpected;
HANDLE _hEvent;
};
class CTimerTest0 : public CTimerTest
{
public:
CTimerTest0()
{
}
~CTimerTest0()
{
UnInitialize();
}
public:
void Initialize()
{
_tprintf( TEXT("Starting a timer with a given due time (%ds)\n"), g_ulDefaultPeriod );
_ulPeriod = g_ulDefaultPeriod;
CTimerTest::Initialize( this, NULL, 0,
_ulPeriod, CNewTimer::NO_RETRY, 0, 0, 0 );
}
public:
void Set()
{
SetSingleShot();
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
}; // class CTimerTest0
class CTimerTest1 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1,
FIRST_RECURRENCE = 2,
FIRST_RETRY = 3,
SECOND_RETRY = 4,
THIRD_RETRY = 5,
FOURTH_RETRY = 6,
SECOND_RECURRENCE = 7,
LAST_RETRY = 8,
FINAL = 9
};
public:
CTimerTest1()
{
_SubPhase = INITIAL;
}
~CTimerTest1()
{
UnInitialize();
}
public:
void Initialize()
{
_tprintf( TEXT("Starting a persistent, recurring, backoff-retry (%d-%ds) timer (%ds)\n"),
g_ulMinRetry, g_ulMaxRetry, g_ulDefaultPeriod );
_ulPeriod = g_ulDefaultPeriod;
CTimerTest::Initialize( this, L"Timer1", 1,
_ulPeriod, CNewTimer::RETRY_WITH_BACKOFF, g_ulMinRetry, g_ulMaxRetry, 0 );
}
public:
void Set()
{
SetRecurring();
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
SUB_PHASE_ENUM _SubPhase;
}; // class CTimerTest1
class CTimerTest2 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1,
RESET = 2,
FINAL = 3
};
public:
CTimerTest2()
{
_SubPhase = INITIAL;
}
~CTimerTest2()
{
UnInitialize();
}
public:
void Initialize()
{
_tprintf( TEXT("Starting a persistent, recurring, non-retrying timer (%ds)\n"),
g_ulDefaultPeriod );
_ulPeriod = g_ulDefaultPeriod;
CTimerTest::Initialize( this, L"Timer2", 2,
_ulPeriod, CNewTimer::NO_RETRY, 0, 0, 0 );
}
public:
void Set()
{
SetRecurring();
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
SUB_PHASE_ENUM _SubPhase;
}; // class CTimerTest1
class CTimerTest3 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1,
FINAL = 2
};
public:
CTimerTest3()
{
_SubPhase = INITIAL;
}
~CTimerTest3()
{
UnInitialize();
}
public:
void Initialize()
{
CFILETIME cftNow;
LONG lRet;
_tprintf( TEXT("Continuing a persistent timer (0s)\n") );
SetTimerRegistryValue( TEXT("Timer3"), 0, cftNow-1, 0 );
// We set a period, but it should really go off immediately because
// of the registry value we just set.
_ulPeriod = g_ulDefaultPeriod;
CTimerTest::Initialize( this, // PTimerCallback
L"Timer3", // Timer name
3, // Timer context
_ulPeriod, // Period in seconds
CNewTimer::NO_RETRY,
0, 0, 0 ); // Lower, upper, max retry times.
}
public:
void Set()
{
SetSingleShot( CFILETIME() - 1 );
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
SUB_PHASE_ENUM _SubPhase;
}; // class CTimerTest1
class CTimerTest4 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1,
SECOND = 2,
THIRD = 3,
FOURTH = 4,
FINAL = 5
};
public:
CTimerTest4()
{
_SubPhase = INITIAL;
}
~CTimerTest4()
{
UnInitialize();
}
public:
void Initialize()
{
_tprintf( TEXT("Starting a non-persistent timer with max lifetime\n") );
_ulPeriod = g_ulDefaultPeriod;
CTimerTest::Initialize( this, // PTimerCallback
NULL, // Timer name
4, // Timer context
_ulPeriod, // Period in seconds
CNewTimer::RETRY_WITH_BACKOFF,
g_ulDefaultPeriod/2, // Min retry
g_ulDefaultPeriod * 2, // Max retry
// Max lifetime
g_ulDefaultPeriod + g_ulDefaultPeriod/2 + g_ulDefaultPeriod + 2*g_ulDefaultPeriod + g_ulDefaultPeriod/4 );
}
public:
void Set()
{
SetSingleShot();
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
SUB_PHASE_ENUM _SubPhase;
}; // class CTimerTest4
class CTimerTest5 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1
};
public:
CTimerTest5()
{
_SubPhase = INITIAL;
}
~CTimerTest5()
{
UnInitialize();
}
public:
void Initialize()
{
_tprintf( TEXT("Starting a generic timer (%ds)\n"), g_ulDefaultPeriod * 2 );
_ulPeriod = g_ulDefaultPeriod * 2;
CTimerTest::Initialize( this, // PTimerCallback
NULL, // Timer name
5, // Timer context
_ulPeriod, // Period in seconds
CNewTimer::NO_RETRY,
0, 0, 0 ); // Min, max retry, max lifetime
}
public:
void Set()
{
SetSingleShot();
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
SUB_PHASE_ENUM _SubPhase;
}; // class CTimerTest4
class CTimerTest6 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1,
FIRST_RECURRENCE = 2,
FIRST_RETRY = 3,
SECOND_RETRY = 4,
THIRD_RETRY = 5,
FOURTH_RETRY = 6,
FINAL = 7
};
public:
CTimerTest6()
{
_cftLower = 0;
_cftUpper = 0;
_cftLastSet = 0;
_SubPhase = INITIAL;
}
~CTimerTest6()
{
UnInitialize();
}
public:
void Initialize()
{
_tprintf( TEXT("Continuing a persistent, recurring, random-retry (%d-%ds) timer (%ds)\n"),
g_ulMinRetry, g_ulMaxRetry, g_ulDefaultPeriod );
_ulPeriod = g_ulDefaultPeriod;
CFILETIME cftDue;
cftDue.IncrementSeconds( _ulPeriod );
SetTimerRegistryValue( TEXT("Timer6"), 0, cftDue, 0 );
TrkLog(( TRKDBG_ERROR, TEXT("Timer6 due at %x"), cftDue.LowDateTime() ));
CTimerTest::Initialize( this, TEXT("Timer6"), 6,
_ulPeriod,
CNewTimer::RETRY_RANDOMLY,
g_ulMinRetry, g_ulMaxRetry,
0 ); // No max lifetime
}
public:
void Set()
{
CFILETIME cftExpected;
cftExpected.IncrementSeconds( _ulPeriod );
TrkLog(( TRKDBG_ERROR, TEXT("Timer6 due at %x"), cftExpected.LowDateTime() ));
SetRecurring( cftExpected );
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
CFILETIME _cftLower, _cftUpper, _cftLastSet;
SUB_PHASE_ENUM _SubPhase;
};
class CTimerTest7 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1,
FINAL = 2,
};
public:
CTimerTest7()
{
_SubPhase = INITIAL;
}
~CTimerTest7()
{
UnInitialize();
}
public:
void Initialize()
{
_ulPeriod = g_ulDefaultPeriod;
_tprintf( TEXT("Starting a retrying (%d-%ds) timer (%ds)\n"), _ulPeriod*2, _ulPeriod*4, _ulPeriod );
CTimerTest::Initialize( this, // PTimerCallback
NULL, // Timer name
7, // Timer context
_ulPeriod, // Period in seconds
CNewTimer::RETRY_WITH_BACKOFF,
_ulPeriod*2, _ulPeriod*4, // Min/max retry
0 ); // No max lifetime
}
public:
void Set()
{
SetSingleShot();
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
SUB_PHASE_ENUM _SubPhase;
}; // class CTimerTest7
class CTimerTest8 : public CTimerTest
{
private:
enum SUB_PHASE_ENUM
{
INITIAL = 1,
FIRST_RETRY = 2,
FINAL = 3
};
public:
CTimerTest8()
{
_SubPhase = INITIAL;
}
~CTimerTest8()
{
UnInitialize();
}
public:
void Initialize()
{
_ulPeriod = g_ulDefaultPeriod;
_tprintf( TEXT("Continuing a retrying timer which was already in retry mode\n") );
CFILETIME cftDue, cftSet;
cftSet.DecrementSeconds( _ulPeriod * 2 ); // A regular period, and have the first retry, have already passed
cftDue.IncrementSeconds( _ulPeriod );
SetTimerRegistryValue( TEXT("Timer8"), cftSet, cftDue, _ulPeriod*2 );
CTimerTest::Initialize( this, // PTimerCallback
TEXT("Timer8"), // Timer name
8, // Timer context
_ulPeriod, // Period in seconds
CNewTimer::RETRY_WITH_BACKOFF,
_ulPeriod*2, _ulPeriod*4, // Min/max retry
// The original period, two retries (2/4) and a retry up to the max lifetime
_ulPeriod*(1+2+4+1) );
}
public:
void Set()
{
CFILETIME cftExpected;
cftExpected.IncrementSeconds( _ulPeriod );
SetSingleShot( cftExpected );
}
private:
TimerContinuation Timer( ULONG ulTimerContext );
private:
SUB_PHASE_ENUM _SubPhase;
}; // class CTimerTest8
#endif // #ifndef _TTIMER_HXX_