4287 lines
114 KiB
C++
4287 lines
114 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright (C) 1995-2000 Microsoft Corporation
|
|
//
|
|
// @doc
|
|
//
|
|
// @module IDBAsynch.cpp | This module tests the OLEDB IDBAsynchStatus interface
|
|
//
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Includes
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#define DBINITCONSTANTS // Must be defined to initialize constants in OLEDB.H
|
|
#define INITGUID
|
|
#include "modstandard.hpp"
|
|
#include "IDBAsynch.h"
|
|
#include "extralib.h"
|
|
#include "olectl.h" //CONNECT_E_NOCONNECT
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Module Values
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// {{ TCW_MODULE_GLOBALS
|
|
//DECLARE_MODULE_CLSID = { 0x17dff980, 0x64a3, 0x11ce, { 0xb1, 0x24, 0x00, 0xaa, 0x00, 0x57, 0x59, 0x9e }};
|
|
DECLARE_MODULE_CLSID = { 0xc661f260, 0x799f, 0x4c2c, {0xbb, 0x58, 0x29, 0xa7, 0xba, 0xc7, 0x74, 0x1f}};
|
|
DECLARE_MODULE_NAME("IDBAsynch");
|
|
DECLARE_MODULE_OWNER("Microsoft");
|
|
DECLARE_MODULE_DESCRIP("IDBAsynchStatus Interface test");
|
|
DECLARE_MODULE_VERSION(795921705);
|
|
// TCW_WizardVersion(2)
|
|
// TCW_Automation(False)
|
|
// }} TCW_MODULE_GLOBALS_END
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Defines
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#define INVALID_PUNK INVALID(IUnknown*)
|
|
#define INVALID_COOKIE INVALID(DWORD)
|
|
#define PROPVAL_NEGATIVE (-0x1)
|
|
|
|
#define TEST_SUPPORTED_PROP(p, pset) { TESTB = TEST_PASS; if(!SupportedProperty(p, pset)) { TOUTPUT_LINE(L#p <<" is not supported"); TESTB = TEST_SKIPPED; TRETURN; } }
|
|
|
|
#define TEST_SETTABLE_PROP(p, pset) { TESTB = TEST_PASS; if(!SettableProperty(p, pset)) { TOUTPUT_LINE(L#p<< " is not settable"); TESTB = TEST_SKIPPED; TRETURN; } }
|
|
|
|
|
|
enum ERESULT
|
|
{
|
|
OP_ABORTED = 0x00000001,
|
|
OP_COMPLETED = 0x00000002,
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Forwards
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class CSource;
|
|
class CListener;
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level initialization routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleInit(CThisTestModule * pThisTestModule)
|
|
{
|
|
//NOTE: This test does numerous different "sources" for connection points, which
|
|
//are determined in the Initialization. So we really can't skip the entire test up
|
|
//front since their may be some source of notifications supported.
|
|
//(Rowset, DataSource, Row, etc)
|
|
BOOL bResult = CommonModuleInit(pThisTestModule, IID_IUnknown);
|
|
if(bResult == TRUE)
|
|
{
|
|
//Make sure that at least one of the connection point sources are available...
|
|
TEST_PROVIDER
|
|
(
|
|
SupportedInterface(IID_IDBAsynchNotify, ROWSET_INTERFACE) ||
|
|
SupportedInterface(IID_IDBAsynchNotify, ROW_INTERFACE) ||
|
|
SupportedInterface(IID_IDBAsynchNotify, DATASOURCE_INTERFACE)
|
|
);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func Module level termination routine
|
|
//
|
|
// @rdesc Success or Failure
|
|
// @flag TRUE | Successful initialization
|
|
// @flag FALSE | Initialization problems
|
|
//
|
|
BOOL ModuleTerminate(CThisTestModule * pThisTestModule)
|
|
{
|
|
return CommonModuleTerminate(pThisTestModule);
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CConnectInfo
|
|
//
|
|
// Just a simple class to track connection info
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CConnectInfo
|
|
{
|
|
public:
|
|
//Constructors
|
|
CConnectInfo(DWORD dwCookie, CListener* pCListener, CSource* pCSource)
|
|
{
|
|
ASSERT(dwCookie);
|
|
ASSERT(pCSource);
|
|
ASSERT(pCListener);
|
|
|
|
m_dwCookie = dwCookie;
|
|
m_pCSource = pCSource;
|
|
m_pCListener = pCListener;
|
|
}
|
|
|
|
virtual ~CConnectInfo()
|
|
{
|
|
}
|
|
|
|
//protected:
|
|
//data
|
|
DWORD m_dwCookie;
|
|
CSource* m_pCSource;
|
|
CListener* m_pCListener;
|
|
};
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CSource (abstract class)
|
|
//
|
|
// Basically an abstract object that is the "source" of the notifications / connectionpoint
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CSource
|
|
{
|
|
public:
|
|
//Constructors
|
|
CSource(REFIID riid, EINTERFACE eObject);
|
|
virtual ~CSource();
|
|
|
|
//pure virtual members
|
|
virtual BOOL CreateSource() = 0;
|
|
virtual BOOL CauseNotification() = 0;
|
|
|
|
//Helpers
|
|
virtual BOOL ReleaseCP();
|
|
virtual BOOL CreateCP(IUnknown* pIUnknown);
|
|
virtual BOOL VerifyNotification(CListener* pCListener, ULONG ulTimesConnected);
|
|
|
|
//Interface
|
|
virtual IConnectionPointContainer* const pICPC() { ASSERT(m_pIConnectionPointContainer); return m_pIConnectionPointContainer; }
|
|
virtual IEnumConnectionPoints* const pIEnumCP() { ASSERT(m_pIEnumConnectionPoints); return m_pIEnumConnectionPoints; }
|
|
|
|
virtual ULONG GetCountCP() { return m_cConnectionPoints; }
|
|
virtual IConnectionPoint* GetCP(ULONG iIndex = 0) { ASSERT(iIndex < m_cConnectionPoints); return m_rgConnectionPoints[iIndex]; }
|
|
virtual REFIID GetIID() { return m_iid; }
|
|
virtual EINTERFACE GetObjectType() { return m_eObject; }
|
|
|
|
protected:
|
|
//Container
|
|
IConnectionPointContainer* m_pIConnectionPointContainer;
|
|
IEnumConnectionPoints* m_pIEnumConnectionPoints;
|
|
|
|
//Connection Points
|
|
ULONG m_cConnectionPoints;
|
|
IConnectionPoint** m_rgConnectionPoints;
|
|
|
|
//Data
|
|
IID m_iid;
|
|
EINTERFACE m_eObject;
|
|
};
|
|
|
|
|
|
CSource::CSource(REFIID riid, EINTERFACE eObject)
|
|
{
|
|
//Container
|
|
m_pIConnectionPointContainer = NULL;
|
|
m_pIEnumConnectionPoints = NULL;
|
|
|
|
//Connection Points
|
|
m_cConnectionPoints = 0;
|
|
m_rgConnectionPoints = NULL;
|
|
|
|
//Type of Objects
|
|
m_iid = riid;
|
|
m_eObject = eObject;
|
|
}
|
|
|
|
CSource::~CSource()
|
|
{
|
|
ReleaseCP();
|
|
}
|
|
|
|
BOOL CSource::ReleaseCP()
|
|
{
|
|
ULONG i = 0;
|
|
//Container
|
|
SAFE_RELEASE(m_pIConnectionPointContainer);
|
|
SAFE_RELEASE(m_pIEnumConnectionPoints);
|
|
|
|
//Connection Points
|
|
for(i=0; i<m_cConnectionPoints; i++)
|
|
SAFE_RELEASE(m_rgConnectionPoints[i]);
|
|
SAFE_FREE(m_rgConnectionPoints);
|
|
m_cConnectionPoints = 0;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CSource::CreateCP(IUnknown* pIUnknown)
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 0;
|
|
IConnectionPoint* pICP = NULL;
|
|
BOOL fSupportedCP = FALSE;
|
|
IID iid;
|
|
|
|
//Release any previous interfaces...
|
|
ReleaseCP();
|
|
|
|
//Obtain the connection point container
|
|
QTESTC_((QI(pIUnknown, IID_IConnectionPointContainer, (void**)&m_pIConnectionPointContainer)),S_OK);
|
|
|
|
//Make sure this connection supports the connection point were interested in...
|
|
QTESTC_(m_pIConnectionPointContainer->FindConnectionPoint(m_iid, &pICP),S_OK);
|
|
SAFE_RELEASE(pICP);
|
|
|
|
//Obtain the IEnumConnectionPoints
|
|
TESTC_(m_pIConnectionPointContainer->EnumConnectionPoints(&m_pIEnumConnectionPoints),S_OK);
|
|
|
|
//Obtain all the Connection Points
|
|
m_cConnectionPoints = 0;
|
|
SAFE_ALLOC(m_rgConnectionPoints, IConnectionPoint*, m_cConnectionPoints + 1);
|
|
|
|
//Obtain all connection points...
|
|
while(SUCCEEDED(pIEnumCP()->Next(1, &pICP, &cFetched)) && cFetched == 1)
|
|
{
|
|
m_rgConnectionPoints[m_cConnectionPoints] = pICP;
|
|
SAFE_REALLOC(m_rgConnectionPoints, IConnectionPoint*, m_cConnectionPoints + 1 + 1);
|
|
|
|
//To make our life easier, lets place the desired ConnectionPoint, first in the list
|
|
//so we can easily access it and distingush it from the other connection points. We just
|
|
//need to swap it with the first element of the array...
|
|
TESTC_(pICP->GetConnectionInterface(&iid),S_OK);
|
|
if(iid == m_iid && !fSupportedCP)
|
|
{
|
|
m_rgConnectionPoints[m_cConnectionPoints] = m_rgConnectionPoints[0];
|
|
m_rgConnectionPoints[0] = pICP;
|
|
fSupportedCP = TRUE;
|
|
}
|
|
|
|
//Increment total connection points...
|
|
m_cConnectionPoints++;
|
|
}
|
|
|
|
//Make sure that we found the connection point in the enumeration
|
|
TESTC(m_cConnectionPoints >= 1);
|
|
TESTC_(m_rgConnectionPoints[0]->GetConnectionInterface(&iid),S_OK);
|
|
TESTC(iid == m_iid);
|
|
|
|
CLEANUP:
|
|
return fSupportedCP;
|
|
}
|
|
|
|
BOOL CSource::VerifyNotification(CListener* pCListener, ULONG ulTimesConnected)
|
|
{
|
|
ASSERT(pCListener);
|
|
TBEGIN
|
|
|
|
TESTC(pCListener->GetTimesNotified() >= ulTimesConnected);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynch
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynch : public CSource
|
|
{
|
|
public:
|
|
CAsynch(REFIID riid, EINTERFACE eObject);
|
|
virtual ~CAsynch();
|
|
|
|
//Pure Virtual
|
|
virtual BOOL CreateCP(IUnknown* pIUnknown);
|
|
virtual BOOL ResetSource(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
virtual BOOL VerifyNotification(CListener* pCListener, DWORD dwResult, ULONG ulTimesConnected);
|
|
virtual BOOL ReleaseSource();
|
|
|
|
//Helpers (Wrappers)
|
|
virtual HRESULT Abort(ULONG ulOperation = DBASYNCHOP_OPEN);
|
|
virtual HRESULT GetStatus(DBCOUNTITEM *pulProgress = NULL, DBCOUNTITEM* pulProgressMax = NULL, ULONG* pulAsynchPhase = NULL, LPOLESTR* ppwszStatusText = NULL);
|
|
virtual HRESULT GetStatus(ULONG ulOperation, DBCOUNTITEM *pulProgress = NULL, DBCOUNTITEM* pulProgressMax = NULL, ULONG* pulAsynchPhase = NULL, LPOLESTR* ppwszStatusText = NULL);
|
|
|
|
//Verification
|
|
virtual BOOL VerifyAbort();
|
|
virtual BOOL VerifyZombie();
|
|
|
|
//Helpers
|
|
virtual HRESULT WaitUntilComplete();
|
|
virtual BOOL IsComplete();
|
|
virtual BOOL IsAsynch() { return (m_ulAsynch != 0); }
|
|
|
|
//Helpers
|
|
virtual DBCOUNTITEM GetProgress() { return m_ulProgress; }
|
|
virtual DBCOUNTITEM GetProgressMax() { return m_ulProgressMax; }
|
|
virtual ULONG GetAsynchPhase() { return m_ulAsynchPhase; }
|
|
virtual WCHAR* GetStatusText() { return m_pwszStatusText; }
|
|
|
|
virtual DBCOUNTITEM GetPrevProgress() { return m_ulPrevProgress; }
|
|
virtual DBCOUNTITEM GetPrevProgressMax() { return m_ulPrevProgressMax; }
|
|
virtual ULONG GetPrevAsynchPhase() { return m_ulPrevAsynchPhase; }
|
|
virtual WCHAR* GetPrevStatusText() { return m_pwszPrevStatusText; }
|
|
|
|
//Interface
|
|
virtual IDBAsynchStatus* const pIDBAsynchStatus() { ASSERT(m_pIDBAsynchStatus); return m_pIDBAsynchStatus; }
|
|
|
|
protected:
|
|
DBCOUNTITEM m_ulProgress;
|
|
DBCOUNTITEM m_ulProgressMax;
|
|
ULONG m_ulAsynchPhase;
|
|
WCHAR* m_pwszStatusText;
|
|
|
|
//Previous Items
|
|
DBCOUNTITEM m_ulPrevProgress;
|
|
DBCOUNTITEM m_ulPrevProgressMax;
|
|
ULONG m_ulPrevAsynchPhase;
|
|
WCHAR* m_pwszPrevStatusText;
|
|
|
|
//data
|
|
IDBAsynchStatus* m_pIDBAsynchStatus;
|
|
|
|
//data
|
|
ULONG_PTR m_ulAsynch;
|
|
DWORD m_dwAsynchPropVal;
|
|
DWORD m_dwAsynchSupport;
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynch
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CAsynch::CAsynch(REFIID riid, EINTERFACE eObject)
|
|
: CSource(riid, eObject)
|
|
{
|
|
m_ulProgress = 0;
|
|
m_ulProgressMax = 0;
|
|
m_ulAsynchPhase = 0;
|
|
m_pwszStatusText = NULL;
|
|
|
|
m_ulPrevProgress = 0;
|
|
m_ulPrevProgressMax = 0;
|
|
m_ulPrevAsynchPhase = 0;
|
|
m_pwszPrevStatusText = NULL;
|
|
|
|
m_pIDBAsynchStatus = NULL;
|
|
m_ulAsynch = 0;
|
|
m_dwAsynchPropVal = 0;
|
|
m_dwAsynchSupport = 0;
|
|
}
|
|
|
|
CAsynch::~CAsynch()
|
|
{
|
|
ReleaseSource();
|
|
}
|
|
|
|
|
|
BOOL CAsynch::ReleaseSource()
|
|
{
|
|
CAsynch::ResetSource();
|
|
|
|
//IDBAsynchStatus
|
|
SAFE_RELEASE(m_pIDBAsynchStatus);
|
|
|
|
//Container
|
|
ReleaseCP();
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CAsynch::ResetSource(DWORD dwPropVal)
|
|
{
|
|
m_ulProgress = 0;
|
|
m_ulProgressMax = 0;
|
|
m_ulAsynchPhase = 0;
|
|
SAFE_FREE(m_pwszStatusText);
|
|
|
|
m_ulPrevProgress = 0;
|
|
m_ulPrevProgressMax = 0;
|
|
m_ulPrevAsynchPhase = 0;
|
|
SAFE_FREE(m_pwszPrevStatusText);
|
|
|
|
m_ulAsynch = 0;
|
|
m_dwAsynchPropVal = dwPropVal;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CAsynch::CreateCP(IUnknown* pIUnknown)
|
|
{
|
|
TBEGIN
|
|
ASSERT(pIUnknown);
|
|
|
|
//Release the Previous interfaces...
|
|
ReleaseSource();
|
|
|
|
//Setup Connection Point Stuff
|
|
QTESTC(CSource::CreateCP(pIUnknown));
|
|
|
|
//Try to obtain the IDBAsynchStatus interface
|
|
QTESTC_(QI(pIUnknown, IID_IDBAsynchStatus, (void**)&m_pIDBAsynchStatus), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
HRESULT CAsynch::Abort(ULONG ulOperation)
|
|
{
|
|
//IDBAsynchStatus::Abort
|
|
return pIDBAsynchStatus()->Abort(DB_NULL_HCHAPTER, ulOperation);
|
|
}
|
|
|
|
HRESULT CAsynch::GetStatus(DBCOUNTITEM *pulProgress, DBCOUNTITEM* pulProgressMax, ULONG* pulAsynchPhase, LPOLESTR* ppwszStatusText)
|
|
{
|
|
//Delegate
|
|
return GetStatus(DBASYNCHOP_OPEN, pulProgress, pulProgressMax, pulAsynchPhase, ppwszStatusText);
|
|
}
|
|
|
|
HRESULT CAsynch::GetStatus(ULONG ulOperation, DBCOUNTITEM *pulProgress, DBCOUNTITEM* pulProgressMax, ULONG* pulAsynchPhase, LPOLESTR* ppwszStatusText)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
m_ulPrevProgress = m_ulProgress;
|
|
m_ulPrevProgressMax = m_ulProgressMax;
|
|
m_ulPrevAsynchPhase = m_ulAsynchPhase;
|
|
|
|
SAFE_FREE(m_pwszPrevStatusText);
|
|
m_pwszPrevStatusText= m_pwszStatusText;
|
|
m_pwszStatusText = NULL;
|
|
|
|
//IDBAsynchStatus::GetStatus
|
|
hr = pIDBAsynchStatus()->GetStatus(DB_NULL_HCHAPTER, ulOperation, &m_ulProgress, &m_ulProgressMax, &m_ulAsynchPhase, &m_pwszStatusText);
|
|
TRACE(L"IDBAsynchStatus::GetStatus(DB_NULL_HCHAPTER, %s, %d, %d, %s, \"%s\"\n", ulOperation==DBASYNCHOP_OPEN ? L"DBASYNCHOP_OPEN" : L"(Unknown)", m_ulProgress, m_ulProgressMax, ::GetAsynchPhase(m_ulAsynchPhase), m_pwszStatusText);
|
|
TEST3C_(hr, S_OK, DB_E_CANCELED, E_UNEXPECTED);
|
|
|
|
//Verify Results
|
|
TESTC(m_ulAsynchPhase >= m_ulPrevAsynchPhase);
|
|
|
|
//Verify HRESULT matches Phase
|
|
if(hr == DB_E_CANCELED)
|
|
{
|
|
TESTC(m_ulProgress < m_ulProgressMax);
|
|
TESTC(m_ulAsynchPhase == DBASYNCHPHASE_CANCELED);
|
|
}
|
|
else
|
|
{
|
|
TESTC(m_ulProgress <= m_ulProgressMax);
|
|
TESTC(m_ulAsynchPhase == DBASYNCHPHASE_INITIALIZATION || m_ulAsynchPhase == DBASYNCHPHASE_POPULATION || m_ulAsynchPhase == DBASYNCHPHASE_COMPLETE);
|
|
}
|
|
|
|
//Warnings
|
|
if(m_ulProgress < m_ulPrevProgress)
|
|
TWARNING("GetStatus() Previous Progress = " << m_ulPrevProgress << " Current Progress = " << m_ulProgress);
|
|
if(m_ulProgressMax < m_ulPrevProgressMax)
|
|
TWARNING("GetStatus() Previous ProgressMax = " << m_ulPrevProgressMax << " Current ProgressMax = " << m_ulProgressMax);
|
|
if(m_pwszStatusText)
|
|
TWARNING("GetStatus() Unable to verify text \"" << m_pwszStatusText << "\"");
|
|
|
|
CLEANUP:
|
|
if(pulProgress)
|
|
*pulProgress = m_ulProgress;
|
|
if(pulProgressMax)
|
|
*pulProgressMax = m_ulProgressMax;
|
|
if(pulAsynchPhase)
|
|
*pulAsynchPhase = m_ulAsynchPhase;
|
|
if(ppwszStatusText)
|
|
*ppwszStatusText = m_pwszStatusText;
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL CAsynch::VerifyAbort()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
//Abort
|
|
hr = Abort();
|
|
TESTC(hr==S_OK || hr==DB_E_CANTCANCEL);
|
|
|
|
if(hr==S_OK)
|
|
{
|
|
if(GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION)
|
|
{
|
|
WaitUntilComplete();
|
|
QTESTC(VerifyZombie());
|
|
}
|
|
else //DBASYNCHPHASE_POPULATION or DBASYNCHPHASE_COMPLETE
|
|
{
|
|
//Should not be Zombied, usable
|
|
TESTC_(GetStatus(), DB_E_CANCELED);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TESTC_(GetStatus(), S_OK);
|
|
TWARNING("Unable to Abort operation?");
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynch::VerifyZombie()
|
|
{
|
|
TBEGIN
|
|
|
|
//Abort was previsouly called
|
|
TESTC_(GetStatus(), E_UNEXPECTED);
|
|
TESTC_(Abort(), E_UNEXPECTED);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CAsynch::IsComplete()
|
|
{
|
|
//IDBAsynchStatus::GetStatus
|
|
HRESULT hr = GetStatus();
|
|
|
|
//Exit if were done...
|
|
if(GetAsynchPhase() == DBASYNCHPHASE_COMPLETE)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
HRESULT CAsynch::WaitUntilComplete()
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
//We need to poll the Status until its complete
|
|
while(TRUE)
|
|
{
|
|
//IDBAsynchStatus::GetStatus
|
|
hr = GetStatus();
|
|
|
|
//If an error occurred return the error
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
//Check for an error in the provider
|
|
if(GetAsynchPhase()!=DBASYNCHPHASE_INITIALIZATION && GetAsynchPhase()!=DBASYNCHPHASE_POPULATION && GetAsynchPhase()!=DBASYNCHPHASE_COMPLETE)
|
|
return E_FAIL;
|
|
|
|
//As soon as we have S_OK and COMPLETE we are done...
|
|
if(GetAsynchPhase()==DBASYNCHPHASE_COMPLETE)
|
|
break;
|
|
|
|
//Sleep a little, so we don't have such a tight loop...
|
|
Sleep(100);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL CAsynch::VerifyNotification(CListener* pCListener, DWORD dwResult, ULONG ulTimesConnected)
|
|
{
|
|
TBEGIN
|
|
if(IsAsynch())
|
|
{
|
|
TCOMPARE_(pCListener->GetTimesNotified() >= ulTimesConnected);
|
|
|
|
//Verify Correct Notifications
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONLOWRESOURCE) == 0);
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONSTOP) == 1*ulTimesConnected);
|
|
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION) >= 0*ulTimesConnected);
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_INITIALIZATION) >= 0*ulTimesConnected);
|
|
|
|
//If tried to Abort the Operation
|
|
//We have 3 options
|
|
// 1. Abort, and operation continued (CantCancel or Veto'd the abort)
|
|
// 2. Abort, and operation was aborted
|
|
// 3. Operation completed as expected
|
|
|
|
if(dwResult & OP_ABORTED)
|
|
{
|
|
if(dwResult & OP_COMPLETED)
|
|
{
|
|
//1. Abort, and operation continued (CantCancel or Veto'd the abort)
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE) == 1*ulTimesConnected);
|
|
}
|
|
else
|
|
{
|
|
//2. Abort, and operation was aborted
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE) == 0*ulTimesConnected);
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED) == 1*ulTimesConnected);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//3. Operation completed as expected
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE) == 1*ulTimesConnected);
|
|
TCOMPARE_(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED) == 0*ulTimesConnected);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//We should not receive notifications if we are not in Asynch mode
|
|
if(pCListener->GetTimesNotified() != 0)
|
|
{
|
|
TERROR("Received Notifications but not in Asynch mode!");
|
|
}
|
|
}
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Class CDataSource
|
|
//
|
|
// Basically a nice wrapper arround a CAsynchDSO.
|
|
// Allows creation and manipulation of asynchronous and
|
|
// sycnhronous DSO's
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynchDSO : public CDataSource, public CAsynch
|
|
{
|
|
public:
|
|
//contsructor
|
|
CAsynchDSO();
|
|
virtual ~CAsynchDSO();
|
|
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL ResetSource(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
virtual BOOL CauseNotification();
|
|
virtual BOOL VerifyZombie();
|
|
|
|
//Helpers
|
|
virtual HRESULT Initialize(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
|
|
protected:
|
|
//data
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynchDSO
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CAsynchDSO::CAsynchDSO()
|
|
: CDataSource(INVALID(WCHAR*)), CAsynch(IID_IDBAsynchNotify, DATASOURCE_INTERFACE)
|
|
{
|
|
}
|
|
|
|
CAsynchDSO::~CAsynchDSO()
|
|
{
|
|
}
|
|
|
|
BOOL CAsynchDSO::CreateSource()
|
|
{
|
|
TBEGIN
|
|
|
|
//Create an Instance first, so we can hook up out listeners,
|
|
//before any notifications
|
|
TESTC_(CDataSource::CreateInstance(),S_OK);
|
|
|
|
//Now that we have a DataSource, obtain Connection stuff
|
|
QTESTC(CreateCP(m_pIDBInitialize));
|
|
|
|
CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
BOOL CAsynchDSO::ResetSource(DWORD dwPropVal)
|
|
{
|
|
CAsynch::ResetSource(dwPropVal);
|
|
return CreateSource();
|
|
}
|
|
|
|
BOOL CAsynchDSO::CauseNotification()
|
|
{
|
|
CAsynch::ResetSource();
|
|
HRESULT hr = Initialize();
|
|
|
|
return hr == S_OK || hr == DB_S_ASYNCHRONOUS;
|
|
}
|
|
|
|
|
|
BOOL CAsynchDSO::VerifyZombie()
|
|
{
|
|
TBEGIN
|
|
|
|
//Verify DataSource is Zombied
|
|
TESTC_(m_pIDBInitialize->Initialize(), E_UNEXPECTED);
|
|
|
|
//Verify Asynch Interface is Zombied
|
|
QTESTC(CAsynch::VerifyZombie());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
HRESULT CAsynchDSO::Initialize(DWORD dwPropVal)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
//May need to create the DataSource (CoCreate)
|
|
if(m_pIDBInitialize == NULL)
|
|
TESTC(CreateSource())
|
|
else
|
|
hr = CDataSource::Uninitialize();
|
|
|
|
|
|
//Set DBPROP_INIT_ASYNCH (if Settable)
|
|
//We may be testing negative cases, so set it if its not a valid value...
|
|
FreeProperties();
|
|
|
|
if (dwPropVal == DBPROPVAL_ASYNCH_INITIALIZE)
|
|
TESTC(SetSettableProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)(ULONG_PTR)dwPropVal, DBTYPE_I4))
|
|
else
|
|
//may test invalid cases
|
|
SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)(ULONG_PTR)dwPropVal, DBTYPE_I4);
|
|
|
|
//Initialize
|
|
//Had better be Asynchronous if were are getting this far...
|
|
hr = CDataSource::Initialize();
|
|
QTESTC(hr==S_OK || hr==DB_S_ASYNCHRONOUS);
|
|
|
|
if(hr == S_OK)
|
|
{
|
|
//Provider Supports IDBAsynchNotify,
|
|
//Execution completely immediatly!
|
|
m_ulAsynch = 0;
|
|
|
|
//This is kind of a wierd state to verify programmically
|
|
//The spec actually allows S_OK, for those causes were Initalization
|
|
//occurs immediatly. Normally DB_S_ASYNCHRONOUS should be returned
|
|
//to inform the consumer to consintue with their tasks...
|
|
TWARNING("IDBInitialize::Initialize returned S_OK, is the DataSource created Immediatly?");
|
|
}
|
|
else if(SUCCEEDED(QI(m_pIDBInitialize, IID_IDBProperties)))
|
|
{
|
|
//DBPROP_INIT_ASYNCH
|
|
//We may not be able to obtain the IDBProperties interface to determine
|
|
//asynch status, so if not we have to total base it on the return code
|
|
TESTC(GetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, m_pIDBInitialize, &m_ulAsynch));
|
|
TESTC(m_ulAsynch & DBPROPVAL_ASYNCH_INITIALIZE);
|
|
}
|
|
else
|
|
{
|
|
m_ulAsynch = DBPROPVAL_ASYNCH_INITIALIZE;
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynchRowset
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynchRowset : public CRowset, public CAsynch
|
|
{
|
|
public :
|
|
//Constructors
|
|
CAsynchRowset(EQUERY eQuery = USE_SUPPORTED_SELECT_ALLFROMTBL);
|
|
virtual ~CAsynchRowset();
|
|
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL ResetSource(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
virtual BOOL CauseNotification();
|
|
virtual BOOL VerifyZombie();
|
|
|
|
//Helpers
|
|
//virtual HRESULT CreateRowset(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
virtual BOOL CreateRowset(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
protected:
|
|
//data
|
|
EQUERY m_eQuery;
|
|
};
|
|
|
|
|
|
CAsynchRowset::CAsynchRowset(EQUERY eQuery)
|
|
: CRowset(INVALID(WCHAR*)), CAsynch(IID_IDBAsynchNotify, ROWSET_INTERFACE)
|
|
{
|
|
m_eQuery = eQuery;
|
|
}
|
|
|
|
CAsynchRowset::~CAsynchRowset()
|
|
{
|
|
}
|
|
|
|
BOOL CAsynchRowset::CreateSource()
|
|
{
|
|
TBEGIN
|
|
|
|
//CreateRowset
|
|
//HRESULT hr = CreateRowset();
|
|
//QTESTC(hr==S_OK || hr==DB_S_ASYNCHRONOUS);
|
|
QTESTC(CreateRowset(m_dwAsynchPropVal));
|
|
|
|
//Now that we have a rowset object, Initailize our CSource object
|
|
//Since IDBAsynchStatus is OFF the Rowset Object, we actually have to create
|
|
//the Rowset and then connect our listeners (quickly) hoping we didn't miss
|
|
//any notifcations, seems like a flaw in the design?
|
|
QTESTC(CreateCP(pIUnknown()));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchRowset::ResetSource(DWORD dwPropVal)
|
|
{
|
|
TBEGIN
|
|
|
|
//We need to drop the previous rowset...
|
|
CAsynch::ResetSource(dwPropVal);
|
|
DropRowset();
|
|
|
|
//Delegate
|
|
QTESTC(CAsynchRowset::CreateSource());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchRowset::CauseNotification()
|
|
{
|
|
TBEGIN
|
|
|
|
//We need to drop the previous rowset...
|
|
// DropRowset();
|
|
|
|
//Delegate
|
|
// CAsynch::ResetSource();
|
|
// QTESTC(CreateSource());
|
|
|
|
//CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
BOOL CAsynchRowset::VerifyZombie()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
IRowset* pIRowset = NULL;
|
|
|
|
//Verify Rowset is Zombied
|
|
hr = QI(pIUnknown(), IID_IRowset, (void**)&pIRowset);
|
|
TESTC(hr==S_OK || hr==E_NOINTERFACE);
|
|
|
|
//May still be able to get the interface, but it should be usable
|
|
if(hr==S_OK)
|
|
{
|
|
TESTC(pIRowset != NULL);
|
|
TESTC_(pIRowset->RestartPosition(NULL), E_UNEXPECTED);
|
|
}
|
|
|
|
//Verify Asynch Interface is Zombied
|
|
TESTC(CAsynch::VerifyZombie());
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowset);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CAsynchRowset::CreateRowset(DWORD dwPropVal)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
//Drop any previous rowset...
|
|
DropRowset();
|
|
|
|
//Set DBPROP_IConnectionPointContainer (Optional)
|
|
//Problem is that some rowsets (providers) may not support IConnectionPointContainer
|
|
//on the actual rowset, but the Asynch Service Components may support it just
|
|
//so you and get IDBAsynchNotify...
|
|
SetProperty(DBPROP_IConnectionPointContainer, DBPROPSET_ROWSET, (void*)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL);
|
|
|
|
|
|
//Set DBPROP_ROWSET_ASYNCH (if Settable)
|
|
TESTC(SetSettableProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)(ULONG_PTR)dwPropVal, DBTYPE_I4));
|
|
|
|
//Deletgate to our CRowset Object
|
|
//Need to obtain interface, since IAccessor connot be obtained...
|
|
hr = CRowset::CreateRowset(m_eQuery, IID_IUnknown);
|
|
QTESTC(hr==S_OK || hr==DB_S_ASYNCHRONOUS);
|
|
|
|
if(hr==S_OK)
|
|
{
|
|
//Execution Completed Immediatly...
|
|
m_ulAsynch = 0;
|
|
|
|
//This is kind of a wierd state to verify programmically
|
|
//The spec actually allows S_OK, for those causes were Initalization
|
|
//occurs immediatly. Normally DB_S_ASYNCHRONOUS should be returned
|
|
//to inform the consumer to consintue with their tasks...
|
|
|
|
if (dwPropVal & (DBPROPVAL_ASYNCH_INITIALIZE | DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION | DBPROPVAL_ASYNCH_RANDOMPOPULATION))
|
|
{
|
|
TWARNING("Rowset creation returned S_OK, is the rowset was created Immediatly?");
|
|
}
|
|
}
|
|
else if(SUCCEEDED(QI(pIUnknown(), IID_IRowsetInfo)))
|
|
{
|
|
//DBPROP_ROWSET_ASYNCH
|
|
//We may not be able to obtain the IRowsetInfo interface to determine
|
|
//asynch status, so if not we have to total base it on the return code
|
|
TESTC(GetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, &m_ulAsynch));
|
|
TESTC(m_ulAsynch & (DBPROPVAL_ASYNCH_INITIALIZE | DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION | DBPROPVAL_ASYNCH_RANDOMPOPULATION));
|
|
TESTC(m_ulAsynch & dwPropVal);
|
|
}
|
|
else
|
|
{
|
|
//m_ulAsynch = DBPROPVAL_ASYNCH_INITIALIZE;
|
|
m_ulAsynch = dwPropVal;
|
|
}
|
|
|
|
CLEANUP:
|
|
// return hr;
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynchRow
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynchRow : public CRowObject, public CAsynch
|
|
{
|
|
public :
|
|
//Constructors
|
|
CAsynchRow(EQUERY eQuery = USE_OPENROWSET);
|
|
virtual ~CAsynchRow();
|
|
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL ResetSource(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
virtual BOOL CauseNotification();
|
|
virtual BOOL VerifyZombie();
|
|
|
|
//Helpers
|
|
|
|
protected:
|
|
//data
|
|
EQUERY m_eQuery;
|
|
};
|
|
|
|
|
|
CAsynchRow::CAsynchRow(EQUERY eQuery)
|
|
: CRowObject(), CAsynch(IID_IDBAsynchNotify, ROW_INTERFACE)
|
|
{
|
|
m_eQuery = eQuery;
|
|
}
|
|
|
|
CAsynchRow::~CAsynchRow()
|
|
{
|
|
}
|
|
|
|
BOOL CAsynchRow::CreateSource()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
IRow* pIRow = NULL;
|
|
|
|
//Create a row object
|
|
//Row Objects are optional behavior...
|
|
TEST3C_(hr = g_pTable->CreateRowset(m_eQuery, IID_IRow, 0, NULL, (IUnknown**)&pIRow),S_OK,DB_S_NOTSINGLETON,E_NOINTERFACE);
|
|
|
|
//Make sure row objects are really not supported
|
|
if(FAILED(hr))
|
|
{
|
|
TESTC(!SupportedProperty(DBPROP_IRow, DBPROPSET_ROWSET));
|
|
TESTC(!SupportedProperty(DBPROP_IGetRow, DBPROPSET_ROWSET));
|
|
QTESTC(FALSE);
|
|
}
|
|
|
|
//See if connection points are available (more optional behavior),
|
|
TESTC_(SetRowObject(pIRow),S_OK);
|
|
QTESTC(CreateCP(pIRow));
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRow);
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchRow::ResetSource(DWORD dwPropVal)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
//We need to drop the previous rowset...
|
|
CAsynch::ResetSource(dwPropVal);
|
|
|
|
//Delegate
|
|
QTESTC(hr = CreateSource());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchRow::CauseNotification()
|
|
{
|
|
TBEGIN
|
|
|
|
//We need to drop the previous rowset...
|
|
// DropRowset();
|
|
|
|
//Delegate
|
|
// CAsynch::ResetSource();
|
|
// QTESTC(CreateSource());
|
|
|
|
//CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
BOOL CAsynchRow::VerifyZombie()
|
|
{
|
|
TBEGIN
|
|
|
|
//TODO
|
|
|
|
//Verify Asynch Interface is Zombied
|
|
TESTC(CAsynch::VerifyZombie());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynchStream
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynchStream : public CRowObject, public CAsynch
|
|
{
|
|
public :
|
|
//Constructors
|
|
CAsynchStream(EQUERY eQuery = USE_OPENROWSET);
|
|
virtual ~CAsynchStream();
|
|
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL ResetSource(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
virtual BOOL CauseNotification();
|
|
virtual BOOL VerifyZombie();
|
|
|
|
//Helpers
|
|
|
|
protected:
|
|
//data
|
|
EQUERY m_eQuery;
|
|
};
|
|
|
|
|
|
CAsynchStream::CAsynchStream(EQUERY eQuery)
|
|
: CRowObject(), CAsynch(IID_IDBAsynchNotify, STREAM_INTERFACE)
|
|
{
|
|
m_eQuery = eQuery;
|
|
}
|
|
|
|
CAsynchStream::~CAsynchStream()
|
|
{
|
|
}
|
|
|
|
BOOL CAsynchStream::CreateSource()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
IRow* pIRow = NULL;
|
|
IUnknown* pIUnknown = NULL;
|
|
DBORDINAL iCol=0;
|
|
|
|
ULONG cPropSets = 0;
|
|
DBPROPSET* rgPropSets = NULL;
|
|
|
|
//Create a row object
|
|
//Row Objects are optional behavior...
|
|
TEST3C_(hr = g_pTable->CreateRowset(m_eQuery, IID_IRow, cPropSets, rgPropSets, (IUnknown**)&pIRow),S_OK,DB_S_NOTSINGLETON,E_NOINTERFACE);
|
|
|
|
//Make sure row objects are really not supported
|
|
if(FAILED(hr))
|
|
{
|
|
TESTC(!SupportedProperty(DBPROP_IRow, DBPROPSET_ROWSET));
|
|
TESTC(!SupportedProperty(DBPROP_IGetRow, DBPROPSET_ROWSET));
|
|
QTESTC(FALSE);
|
|
}
|
|
|
|
//Now that we have a row object, dump it into our helper CRowObject class...
|
|
TESTC_(SetRowObject(pIRow),S_OK);
|
|
|
|
//See if we can obtain a stream object over any of the columns...
|
|
for(iCol=0; iCol<m_cColAccess; iCol++)
|
|
{
|
|
//Open will mainly only be able to be called for columns containing objects.
|
|
//But some providers might be able to open streams, or other types of objects ontop
|
|
//of non-object valued columns.
|
|
hr = Open(NULL, &m_rgColAccess[iCol].columnid, DBGUID_STREAM, IID_IUnknown, &pIUnknown);
|
|
TEST3C_(hr, S_OK, S_FALSE, DB_E_OBJECTMISMATCH);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//Now that we have a stream object,
|
|
//if it supports connection points, we are done...
|
|
if(CreateCP(pIUnknown))
|
|
break;
|
|
}
|
|
|
|
SAFE_RELEASE(pIUnknown);
|
|
}
|
|
|
|
//At this point we should a stream object, otherwise return false
|
|
QTESTC(pIUnknown != NULL);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIUnknown);
|
|
SAFE_RELEASE(pIRow);
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchStream::ResetSource(DWORD dwPropVal)
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
//We need to drop the previous rowset...
|
|
CAsynch::ResetSource(dwPropVal);
|
|
|
|
//Delegate
|
|
QTESTC(hr = CreateSource());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchStream::CauseNotification()
|
|
{
|
|
TBEGIN
|
|
|
|
//We need to drop the previous rowset...
|
|
// DropRowset();
|
|
|
|
//Delegate
|
|
// CAsynch::ResetSource();
|
|
// QTESTC(CreateSource());
|
|
|
|
//CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
BOOL CAsynchStream::VerifyZombie()
|
|
{
|
|
TBEGIN
|
|
|
|
//TODO
|
|
|
|
//Verify Asynch Interface is Zombied
|
|
TESTC(CAsynch::VerifyZombie());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCBase
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class TCBase
|
|
{
|
|
public:
|
|
//constructor
|
|
TCBase()
|
|
{
|
|
m_dwTestCaseParam = 0;
|
|
}
|
|
|
|
//methods
|
|
virtual void SetTestCaseParam(DWORD dwTestCaseParam)
|
|
{
|
|
m_dwTestCaseParam = dwTestCaseParam;
|
|
}
|
|
|
|
//data
|
|
DWORD m_dwTestCaseParam;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Class CTestNotify
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
class CTestNotify : public COLEDB, public TCBase
|
|
{
|
|
public:
|
|
//contsructor
|
|
CTestNotify(WCHAR * pwszTestCaseName);
|
|
virtual ~CTestNotify();
|
|
|
|
virtual BOOL Init();
|
|
virtual BOOL Terminate();
|
|
|
|
//members
|
|
virtual BOOL InitSources();
|
|
virtual BOOL ResetSources(DWORD dwPropVal = DBPROPVAL_ASYNCH_INITIALIZE);
|
|
virtual BOOL ResetListeners();
|
|
|
|
//Connections
|
|
virtual BOOL CauseNotifications();
|
|
virtual HRESULT WaitUntilComplete();
|
|
|
|
virtual BOOL VerifyAllConnections(DWORD dwResult = OP_COMPLETED);
|
|
virtual BOOL VerifyConnection(CListener* pCListener, CAsynch* pCAsynch, DWORD dwResult = OP_COMPLETED, ULONG ulTimesConnected = ULONG_MAX);
|
|
virtual BOOL VerifyNoConnection();
|
|
|
|
virtual BOOL VerifyEvent(CListener* pCListener, DBASYNCHREASON eReason, DBASYNCHPHASE ePhase = DBEVENTPHASE_ALL);
|
|
virtual BOOL VerifyEventAll(DBASYNCHREASON eReason, DBASYNCHPHASE ePhase = DBEVENTPHASE_ALL);
|
|
virtual BOOL VerifyUnwantedEvent(CListener* pCListener, DBASYNCHREASON eReason, DBASYNCHPHASE ePhase = DBEVENTPHASE_ALL);
|
|
virtual BOOL VerifyUniqueCookie(DWORD dwCookie, CSource* pCSource);
|
|
|
|
//Advise connections
|
|
virtual BOOL AdviseAll();
|
|
virtual BOOL Advise(CListener* pCListener, CSource* pCSource, DWORD* pdwCookie = NULL);
|
|
|
|
//Unadvise Connections
|
|
virtual BOOL UnadviseAll();
|
|
virtual BOOL Unadvise(CListener* pCListener, CSource* pCSource);
|
|
|
|
//Indexing
|
|
virtual CListener* pCListener(ULONG iListener) { return m_vectListeners[iListener]; }
|
|
virtual CAsynch* pCSource(ULONG iSource) { return m_vectSources[iSource]; }
|
|
|
|
protected:
|
|
//Associated (Multiple) Listeners
|
|
CVector<CListener*> m_vectListeners; //array of Listeners
|
|
|
|
//Associated (Multiple) Source
|
|
CVector<CAsynch*> m_vectSources; //array of Sources
|
|
|
|
//Track connections between sources and listeners
|
|
CList<CConnectInfo*, CConnectInfo*> m_listConnectInfo;
|
|
CRITICAL_SECTION ConnTableMutex;
|
|
};
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Class CTestNotify
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
CTestNotify::CTestNotify(WCHAR * pwszTestCaseName): COLEDB(pwszTestCaseName)
|
|
{
|
|
}
|
|
|
|
CTestNotify::~CTestNotify()
|
|
{
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::Init()
|
|
{
|
|
TBEGIN
|
|
ULONG i=0;
|
|
//This must be done and not skipped by any error
|
|
//Since we delete the critical section in the Terminate...
|
|
InitializeCriticalSection(&ConnTableMutex);
|
|
|
|
//Init Listeners
|
|
for(i=0; i<5; i++)
|
|
{
|
|
CListener* pCListener = new CListener(IID_IDBAsynchNotify);
|
|
TESTC(pCListener != NULL);
|
|
|
|
//Make sure it has an extra reference count, so its arround
|
|
//For the lifetime of the TestCase. Otherwise it would be deleted
|
|
//After the first rowset unadvises it. We will call Release in Terminate.
|
|
SAFE_ADDREF(pCListener);
|
|
m_vectListeners.AddElement(pCListener);
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::Terminate()
|
|
{
|
|
DBCOUNTITEM i;
|
|
//Free the list of Sources
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
SAFE_DELETE(m_vectSources[i]);
|
|
m_vectSources.RemoveAll();
|
|
|
|
//Free the list of listeners
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
{
|
|
//Make sure their are no outstanding references on the listeners...
|
|
SAFE_RELEASE_(m_vectListeners[i]);
|
|
}
|
|
m_vectListeners.RemoveAll();
|
|
|
|
|
|
DeleteCriticalSection(&ConnTableMutex);
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::InitSources()
|
|
{
|
|
TBEGIN
|
|
IDBCreateCommand *pIDBCreateCommand = NULL;
|
|
ULONG i = 0;
|
|
// Test if necessary interfaces and properties are supported/settable
|
|
switch(m_dwTestCaseParam)
|
|
{
|
|
case STREAM_INTERFACE:
|
|
case ROW_INTERFACE:
|
|
TEST_PROVIDER(SupportedInterface(IID_IDBAsynchNotify, ROW_INTERFACE));
|
|
TEST_SUPPORTED_PROP(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET);
|
|
TEST_SETTABLE_PROP(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET);
|
|
break;
|
|
|
|
case DATASOURCE_INTERFACE:
|
|
TEST_PROVIDER(SupportedInterface(IID_IDBAsynchNotify, DATASOURCE_INTERFACE));
|
|
TEST_SUPPORTED_PROP(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT);
|
|
TEST_SETTABLE_PROP(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT);
|
|
break;
|
|
|
|
case ROWSET_INTERFACE:
|
|
case COMMAND_INTERFACE:
|
|
case ENUMERATOR_INTERFACE:
|
|
// if Commands are not supported skip and log information
|
|
if (COMMAND_INTERFACE==m_dwTestCaseParam)
|
|
{
|
|
if(!VerifyInterface(g_pIOpenRowset, IID_IDBCreateCommand,
|
|
SESSION_INTERFACE, (IUnknown**)&pIDBCreateCommand))
|
|
{
|
|
TOUTPUT_LINE(L"Commands are not supported by this Provider");
|
|
TESTB = TEST_SKIPPED;
|
|
TRETURN
|
|
}
|
|
SAFE_RELEASE(pIDBCreateCommand);
|
|
}
|
|
TEST_PROVIDER(SupportedInterface(IID_IDBAsynchNotify, ROWSET_INTERFACE));
|
|
TEST_SUPPORTED_PROP(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET);
|
|
TEST_SETTABLE_PROP(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(!L"Unhandled TestCase Type!");
|
|
break;
|
|
}
|
|
|
|
//Init Sources
|
|
for(i=0; i<3; i++)
|
|
{
|
|
CAsynch* pCSource = NULL;
|
|
|
|
//First 2 sources have the possibility of being row sources
|
|
switch(m_dwTestCaseParam)
|
|
{
|
|
case STREAM_INTERFACE:
|
|
pCSource = new CAsynchStream;
|
|
break;
|
|
|
|
case ROW_INTERFACE:
|
|
pCSource = new CAsynchRow;
|
|
break;
|
|
|
|
case DATASOURCE_INTERFACE:
|
|
pCSource = new CAsynchDSO;
|
|
break;
|
|
|
|
case ROWSET_INTERFACE:
|
|
pCSource = new CAsynchRowset;
|
|
break;
|
|
|
|
case COMMAND_INTERFACE:
|
|
pCSource = new CAsynchRowset(SELECT_VALIDATIONORDER);//(SELECT_ORDERBYNUMERIC);
|
|
break;
|
|
|
|
case ENUMERATOR_INTERFACE:
|
|
pCSource = new CAsynchRowset(SELECT_DBSCHEMA_TABLE);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(!L"Unhandled TestCase Type!");
|
|
break;
|
|
};
|
|
|
|
//Initialize the source
|
|
TESTC(pCSource != NULL);
|
|
|
|
//Add this source to the list...
|
|
m_vectSources.AddElement(pCSource);
|
|
TESTC_PROVIDER(pCSource->CreateSource())
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::ResetSources(DWORD dwPropVal)
|
|
{
|
|
TBEGIN
|
|
ULONG i = 0;
|
|
//Reset all listeners
|
|
ResetListeners();
|
|
|
|
//Reset all Sources
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
QTESTC(pCSource(i)->ResetSource(dwPropVal));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::ResetListeners()
|
|
{
|
|
TBEGIN
|
|
ULONG i = 0;
|
|
//Reset all listeners
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
TESTC(pCListener(i)->ResetTimesNotified());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::VerifyUniqueCookie(DWORD dwCookie, CSource* pCSource)
|
|
{
|
|
//NOTE: This method only verifies Cookies from the same Container
|
|
//are unique, since Cookies may not be unqiue accross Containers.
|
|
|
|
//Loop through all the current connection cookies.
|
|
POSITION pos = m_listConnectInfo.GetHeadPosition();
|
|
while(pos)
|
|
{
|
|
//Obtain the connect info
|
|
CConnectInfo* pCConnectInfo = m_listConnectInfo.GetNext(pos);
|
|
|
|
//verify different connection cookies
|
|
//Only compare Cookies from the same Container (CSource)
|
|
if(pCSource == pCConnectInfo->m_pCSource)
|
|
{
|
|
if(dwCookie == pCConnectInfo->m_dwCookie)
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CTestNotify::Advise(CListener* pCListener, CSource* pCSource, DWORD* pdwCookie)
|
|
{
|
|
//Advise iListener -> iSource, and need cookie
|
|
ASSERT(pCListener);
|
|
ASSERT(pCSource);
|
|
|
|
TBEGIN
|
|
DWORD dwCookie = 0;
|
|
CConnectInfo* pCConnectInfo = NULL;
|
|
BOOL bUnique = FALSE;
|
|
|
|
//Record the cuurent ref count
|
|
ULONG cRefCount = GetRefCount(pCListener);
|
|
|
|
//Advise
|
|
TESTC_(pCSource->GetCP()->Advise(pCListener, &dwCookie),S_OK);
|
|
|
|
//verify valid cookie
|
|
TESTC(dwCookie != 0);
|
|
|
|
//Before we add this to the list, verify its a unique cookie...
|
|
//Don't actually exit if it's not as we still need to add it to the list,
|
|
//so we can free it later...
|
|
bUnique = VerifyUniqueCookie(dwCookie, pCSource);
|
|
|
|
//Add this connection info to the list
|
|
EnterCriticalSection(&ConnTableMutex);
|
|
pCConnectInfo = new CConnectInfo(dwCookie, pCListener, pCSource);
|
|
m_listConnectInfo.AddTail(pCConnectInfo);
|
|
LeaveCriticalSection(&ConnTableMutex);
|
|
|
|
//Before we add this to the list, verify its a unique cookie...
|
|
TESTC(bUnique == TRUE);
|
|
|
|
//Verify newly advised connection
|
|
// TESTC(VerifyConnection(pCListener, (CAsynch*)pCSource));
|
|
|
|
//Verify refcount is greater after advise
|
|
TESTC(VerifyRefCounts(GetRefCount(pCListener), cRefCount+1));
|
|
|
|
CLEANUP:
|
|
if(pdwCookie)
|
|
*pdwCookie = dwCookie;
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CTestNotify::Unadvise(CListener* pCListener, CSource* pCSource)
|
|
{
|
|
TBEGIN
|
|
ASSERT(pCListener);
|
|
ASSERT(pCSource);
|
|
|
|
//Record the cuurent ref count
|
|
ULONG cRefCount = GetRefCount(pCListener);
|
|
|
|
//Find Listener/CSource in list
|
|
POSITION pos = m_listConnectInfo.GetHeadPosition();
|
|
while(pos)
|
|
{
|
|
POSITION posSave = pos;
|
|
CConnectInfo* pCConnectInfo = m_listConnectInfo.GetNext(pos);
|
|
if(pCListener == pCConnectInfo->m_pCListener && pCSource == pCConnectInfo->m_pCSource)
|
|
{
|
|
//Unadvise the connection
|
|
TESTC_(pCSource->GetCP()->Unadvise(pCConnectInfo->m_dwCookie),S_OK);
|
|
|
|
//Remove from list
|
|
EnterCriticalSection(&ConnTableMutex);
|
|
m_listConnectInfo.RemoveAt(posSave);
|
|
LeaveCriticalSection(&ConnTableMutex);
|
|
|
|
//Verify ref count
|
|
// TESTC(VerifyConnection(pCListener, (CAsynch*)pCSource));
|
|
TESTC(VerifyRefCounts(GetRefCount(pCListener), cRefCount-1));
|
|
break;
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::AdviseAll()
|
|
{
|
|
TBEGIN
|
|
ULONG iListener = 0;
|
|
ULONG index = 0;
|
|
ULONG iSource = 0;
|
|
//Advise the specified number of connections, and verify
|
|
for(iListener=0, index=0; iListener<m_vectListeners.GetCount(); iListener++)
|
|
{
|
|
for(iSource=0; iSource<m_vectSources.GetCount(); iSource++, index++)
|
|
{
|
|
TESTC(Advise(pCListener(iListener), pCSource(iSource)));
|
|
}
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::UnadviseAll()
|
|
{
|
|
TBEGIN
|
|
|
|
//Unadvise all Cookies in the list
|
|
//NOTE: Unadvise will remove the element from the list so we can
|
|
//just loop until either the list is empty or an error occurs
|
|
while(!m_listConnectInfo.IsEmpty())
|
|
{
|
|
CConnectInfo* pCConnectInfo = m_listConnectInfo.GetHead();
|
|
TESTC(Unadvise(pCConnectInfo->m_pCListener, pCConnectInfo->m_pCSource));
|
|
}
|
|
|
|
//Verify no connection
|
|
// TESTC(VerifyNoConnection());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::CauseNotifications()
|
|
{
|
|
TBEGIN
|
|
ULONG i = 0;
|
|
//Reset all listeners
|
|
// for(ULONG i=0; i<m_vectListeners.GetCount(); i++)
|
|
// TESTC(pCListener(i)->ResetTimesNotified());
|
|
|
|
//verify listener recieved notification
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
QTESTC(pCSource(i)->CauseNotification());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
HRESULT CTestNotify::WaitUntilComplete()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
ULONG i = 0;
|
|
//We need to wait for the Notification or Completion...
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
QTESTC_(hr = pCSource(i)->WaitUntilComplete(),S_OK);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::VerifyAllConnections(DWORD dwResult)
|
|
{
|
|
TBEGIN
|
|
ULONG iListener = 0;
|
|
HRESULT hrExpected = dwResult & OP_COMPLETED ? S_OK : DB_E_CANCELED;
|
|
ULONG iSource = 0;
|
|
//We need to wait for the Notification or Completion...
|
|
TESTC_(WaitUntilComplete(), hrExpected);
|
|
|
|
//verify listener recieved notification
|
|
for(iListener=0; iListener<m_vectListeners.GetCount(); iListener++)
|
|
{
|
|
for(iSource=0; iSource<m_vectSources.GetCount(); iSource++)
|
|
{
|
|
TESTC(VerifyConnection(pCListener(iListener), pCSource(iSource), dwResult));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::VerifyNoConnection()
|
|
{
|
|
TBEGIN
|
|
ULONG i=0;
|
|
|
|
//We need to wait for the Notification or Completion...
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//verify listener recieved notification
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
{
|
|
TESTC(pCListener(i)->GetTimesNotified() == 0);
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CTestNotify::VerifyEventAll(DBASYNCHREASON eReason, DBASYNCHPHASE ePhase)
|
|
{
|
|
TBEGIN
|
|
ULONG i = 0;
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
QTESTC(VerifyEvent(pCListener(i), eReason, ePhase));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CTestNotify::VerifyEvent(CListener* pCListener, DBASYNCHREASON eReason, DBASYNCHPHASE ePhase)
|
|
{
|
|
TBEGIN
|
|
ASSERT(pCListener);
|
|
|
|
//Calculate the number of Asynch Sources we have...
|
|
ULONG cAsynchSources = 0;
|
|
ULONG cRowsetSources = 0;
|
|
ULONG i = 0;
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
{
|
|
if(pCSource(i)->IsAsynch())
|
|
cAsynchSources++;
|
|
if(pCSource(i)->GetObjectType() == ROWSET_INTERFACE)
|
|
cRowsetSources++;
|
|
}
|
|
|
|
switch(eReason)
|
|
{
|
|
case DBREASON_ONLOWRESOURCE:
|
|
{
|
|
//This should never be called
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ONLOWRESOURCE, DBEVENTPHASE_ALL) == 0);
|
|
break;
|
|
}
|
|
|
|
case DBREASON_ONSTOP:
|
|
{
|
|
//This should be called once for each Source
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ONSTOP, DBEVENTPHASE_ALL) == cAsynchSources);
|
|
break;
|
|
}
|
|
|
|
case DBREASON_ONPROGRESS:
|
|
{
|
|
switch(ePhase)
|
|
{
|
|
case DBASYNCHPHASE_INITIALIZATION:
|
|
//This maybe called (basically optional)...
|
|
break;
|
|
|
|
case DBASYNCHPHASE_POPULATION:
|
|
//This maybe called (basically optional)...
|
|
//This notification only is allowed during population of a rowset
|
|
if(cRowsetSources)
|
|
{
|
|
// Optional
|
|
}
|
|
else
|
|
{
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION) == 0);
|
|
}
|
|
break;
|
|
|
|
case DBASYNCHPHASE_COMPLETE:
|
|
//This must be called once for each Source
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE) == cAsynchSources);
|
|
break;
|
|
|
|
case DBEVENTPHASE_ALL:
|
|
//This maybe called (basically optional)...
|
|
|
|
//This maybe called (basically optional)...
|
|
//This notification only is allowed during population of a rowset
|
|
if(cRowsetSources)
|
|
{
|
|
// Optional
|
|
}
|
|
else
|
|
{
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION) == 0);
|
|
}
|
|
|
|
//This must be called once for each Source
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE) == cAsynchSources);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(!"Unhandled Type!");
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
ASSERT(!"Unhandled Type!");
|
|
break;
|
|
};
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CTestNotify::VerifyUnwantedEvent(CListener* pCListener, DBASYNCHREASON eReason, DBASYNCHPHASE ePhase)
|
|
{
|
|
TBEGIN
|
|
ASSERT(pCListener);
|
|
|
|
//Calculate the number of Asynch Sources we have...
|
|
ULONG cAsynchSources = 0;
|
|
ULONG cRowsetSources = 0;
|
|
ULONG i = 0;
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
{
|
|
if(pCSource(i)->IsAsynch())
|
|
cAsynchSources++;
|
|
if(pCSource(i)->GetObjectType() == ROWSET_INTERFACE)
|
|
cRowsetSources++;
|
|
}
|
|
|
|
switch(eReason)
|
|
{
|
|
case DBREASON_ONLOWRESOURCE:
|
|
{
|
|
//This should never be called
|
|
if(pCListener->GetTimesNotified(DBREASON_ONLOWRESOURCE, DBEVENTPHASE_ALL))
|
|
TWARNING("Was notified for unwanted notification IDBAsynchNotify::OnLowResource()");
|
|
break;
|
|
}
|
|
|
|
case DBREASON_ONSTOP:
|
|
{
|
|
//This is an unwanted event, indicate a warning, since it was notified
|
|
if(pCListener->GetTimesNotified(DBREASON_ONSTOP, DBEVENTPHASE_ALL))
|
|
TWARNING("Was notified for unwanted notification IDBAsynchNotify::OnStop()");
|
|
break;
|
|
}
|
|
|
|
case DBREASON_ONPROGRESS:
|
|
{
|
|
switch(ePhase)
|
|
{
|
|
case DBASYNCHPHASE_INITIALIZATION:
|
|
//This maybe called (basically optional)...
|
|
if(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_INITIALIZATION))
|
|
TWARNING("Was notified for unwanted notification IDBAsynchNotify::OnProgress(DBASYNCHPHASE_INITIALIZATION)");
|
|
break;
|
|
|
|
case DBASYNCHPHASE_POPULATION:
|
|
//This maybe called (basically optional)...
|
|
//This notification only is allowed during population of a rowset
|
|
if(cRowsetSources)
|
|
{
|
|
if(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION))
|
|
TWARNING("Was notified for unwanted notification IDBAsynchNotify::OnProgress(DBASYNCHPHASE_POPULATION)");
|
|
}
|
|
else
|
|
{
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION) == 0);
|
|
}
|
|
break;
|
|
|
|
case DBASYNCHPHASE_COMPLETE:
|
|
//This must be called once for each Source
|
|
if(pCListener->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE))
|
|
TWARNING("Was notified for unwanted notification IDBAsynchNotify::OnProgress(DBASYNCHPHASE_COMPLETE)");
|
|
break;
|
|
|
|
case DBEVENTPHASE_ALL:
|
|
//This maybe called (basically optional)...
|
|
if(pCListener->GetTimesNotified(DBREASON_ONPROGRESS))
|
|
TWARNING("Was notified for unwanted notification IDBAsynchNotify::OnProgress(DBASYNCHPHASE_ALL)");
|
|
break;
|
|
|
|
default:
|
|
ASSERT(!"Unhandled Type!");
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
default:
|
|
ASSERT(!"Unhandled Type!");
|
|
break;
|
|
};
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::VerifyConnection(CListener* pCListener, CAsynch* pCAsynch, DWORD dwResult, ULONG ulTimesConnected)
|
|
{
|
|
TBEGIN
|
|
|
|
//Figure out how many times the sink is connected to the source
|
|
if(ulTimesConnected == ULONG_MAX)
|
|
{
|
|
ulTimesConnected = 0;
|
|
POSITION pos = m_listConnectInfo.GetHeadPosition();
|
|
while(pos)
|
|
{
|
|
CConnectInfo* pCConnectInfo = m_listConnectInfo.GetNext(pos);
|
|
if(pCListener == pCConnectInfo->m_pCListener/* && pCAsynch == pCConnectInfo->m_pCSource*/)
|
|
ulTimesConnected++;
|
|
}
|
|
}
|
|
|
|
//verify listener recieved notification
|
|
TESTC(pCAsynch->VerifyNotification(pCListener, dwResult, ulTimesConnected));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Test Case Section
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAsynchNotify)
|
|
//--------------------------------------------------------------------
|
|
// @class Test Notifications
|
|
//
|
|
class TCAsynchNotify : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAsynchNotify,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Test how many times notified
|
|
int Variation_1();
|
|
// @cmember verify multiple Listeners are advised
|
|
int Variation_2();
|
|
// @cmember Verify DBASYNCHPHASE_POPULATION is received
|
|
int Variation_3();
|
|
// @cmember Test DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION
|
|
int Variation_4();
|
|
// @cmember Test DBPROPVAL_ASYNCH_RANDOMPOPULATION
|
|
int Variation_5();
|
|
// @cmember Test SEQUENTIAL | RANDOM
|
|
int Variation_6();
|
|
// @cmember L1 -OnProgress DB_S_UNWANTEDOPERATION L2, L3 receive all phases
|
|
int Variation_7();
|
|
// @cmember L1 -OnStop DB_S_UNWANTEDOPERATION L2, L3 receive all phases
|
|
int Variation_8();
|
|
// @cmember L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases
|
|
int Variation_9();
|
|
// @cmember L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases
|
|
int Variation_10();
|
|
// @cmember L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases
|
|
int Variation_11();
|
|
// @cmember OnLowResource - Veto
|
|
int Variation_12();
|
|
// @cmember OnStop - Veto
|
|
int Variation_13();
|
|
// @cmember OnProgress - Veto CANCELED
|
|
int Variation_14();
|
|
// @cmember OnProgress - Veto INITIALIZATION
|
|
int Variation_15();
|
|
// @cmember OnProgress - Veto POPULATION
|
|
int Variation_16();
|
|
// @cmember OnProgress - Veto COMPLETE
|
|
int Variation_17();
|
|
// @cmember Advise Listener - after operation is complete
|
|
int Variation_18();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCAsynchNotify)
|
|
#define THE_CLASS TCAsynchNotify
|
|
BEG_TEST_CASE(TCAsynchNotify, CTestNotify, L"Test Notifications")
|
|
TEST_VARIATION(1, L"Test how many times notified")
|
|
TEST_VARIATION(2, L"verify multiple Listeners are advised")
|
|
TEST_VARIATION(3, L"Verify DBASYNCHPHASE_POPULATION is received")
|
|
TEST_VARIATION(4, L"Test DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION")
|
|
TEST_VARIATION(5, L"Test DBPROPVAL_ASYNCH_RANDOMPOPULATION")
|
|
TEST_VARIATION(6, L"Test SEQUENTIAL | RANDOM")
|
|
TEST_VARIATION(7, L"L1 -OnProgress DB_S_UNWANTEDOPERATION L2, L3 receive all phases")
|
|
TEST_VARIATION(8, L"L1 -OnStop DB_S_UNWANTEDOPERATION L2, L3 receive all phases")
|
|
TEST_VARIATION(9, L"L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases")
|
|
TEST_VARIATION(10, L"L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases")
|
|
TEST_VARIATION(11, L"L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases")
|
|
TEST_VARIATION(12, L"OnLowResource - Veto")
|
|
TEST_VARIATION(13, L"OnStop - Veto")
|
|
TEST_VARIATION(14, L"OnProgress - Veto CANCELED")
|
|
TEST_VARIATION(15, L"OnProgress - Veto INITIALIZATION")
|
|
TEST_VARIATION(16, L"OnProgress - Veto POPULATION")
|
|
TEST_VARIATION(17, L"OnProgress - Veto COMPLETE")
|
|
TEST_VARIATION(18, L"Advise Listener - after operation is complete")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAsynchNotifyFailure)
|
|
//--------------------------------------------------------------------
|
|
// @class Test Notification Error cases
|
|
//
|
|
class TCAsynchNotifyFailure : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAsynchNotifyFailure,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember E_FAIL - L1 , L1, L2 , L3 receive all phases
|
|
int Variation_1();
|
|
// @cmember E_FAIL - L1 L2 , L1, L2 , L3 receive all phases
|
|
int Variation_2();
|
|
// @cmember E_FAIL - L1 L2 , L1, L2 , L3 receive all phases
|
|
int Variation_3();
|
|
// @cmember E_FAIL - IRowsetLocate
|
|
int Variation_4();
|
|
// @cmember E_FAIL - IRowsetResynch
|
|
int Variation_5();
|
|
// @cmember E_FAIL - IRowsetScroll
|
|
int Variation_6();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCAsynchNotifyFailure)
|
|
#define THE_CLASS TCAsynchNotifyFailure
|
|
BEG_TEST_CASE(TCAsynchNotifyFailure, CTestNotify, L"Test Notification Error cases")
|
|
TEST_VARIATION(1, L"E_FAIL - L1 , L1, L2 , L3 receive all phases")
|
|
TEST_VARIATION(2, L"E_FAIL - L1 L2 , L1, L2 , L3 receive all phases")
|
|
TEST_VARIATION(3, L"E_FAIL - L1 L2 , L1, L2 , L3 receive all phases")
|
|
TEST_VARIATION(4, L"E_FAIL - IRowsetLocate")
|
|
TEST_VARIATION(5, L"E_FAIL - IRowsetResynch")
|
|
TEST_VARIATION(6, L"E_FAIL - IRowsetScroll")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAsynchStatus)
|
|
//--------------------------------------------------------------------
|
|
// @class Test Notification Error cases
|
|
//
|
|
class TCAsynchStatus : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAsynchStatus,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Check the HRESULT from GetStatus
|
|
int Variation_1();
|
|
// @cmember Verify ProgressMax == ProgressCurr
|
|
int Variation_2();
|
|
// @cmember check ulAsynchPhase is DBASYNCHPHASE_COMPLETE
|
|
int Variation_3();
|
|
// @cmember Verify ratio corresponds to returned staus code
|
|
int Variation_4();
|
|
// @cmember Verify ratio of ProgressCurr and ProgressMax
|
|
int Variation_5();
|
|
// @cmember Poll for status continuously
|
|
int Variation_6();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCAsynchStatus)
|
|
#define THE_CLASS TCAsynchStatus
|
|
BEG_TEST_CASE(TCAsynchStatus, CTestNotify, L"Test Notification Error cases")
|
|
TEST_VARIATION(1, L"Check the HRESULT from GetStatus")
|
|
TEST_VARIATION(2, L"Verify ProgressMax == ProgressCurr")
|
|
TEST_VARIATION(3, L"check ulAsynchPhase is DBASYNCHPHASE_COMPLETE")
|
|
TEST_VARIATION(4, L"Verify ratio corresponds to returned staus code")
|
|
TEST_VARIATION(5, L"Verify ratio of ProgressCurr and ProgressMax")
|
|
TEST_VARIATION(6, L"Poll for status continuously")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAsynchAbort)
|
|
//--------------------------------------------------------------------
|
|
// @class Test Notification Error cases
|
|
//
|
|
class TCAsynchAbort : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAsynchAbort,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Call abort after population completed, verify DB_E_CANTCANCEL
|
|
int Variation_1();
|
|
// @cmember GetStatus after Abort returns DB_E_CANTCANCEL returns S_OK
|
|
int Variation_2();
|
|
// @cmember Abort in Initialization phase, Get Status returns DB_E_CANCELED
|
|
int Variation_3();
|
|
// @cmember call GetStaus twice after Abort - E_UNEXPECTED
|
|
int Variation_4();
|
|
// @cmember check population is uncomplete after abort called
|
|
int Variation_5();
|
|
// @cmember Call Abort Again - E_UNEXPECTED
|
|
int Variation_6();
|
|
// @cmember Call OpenRowset again after Abort
|
|
int Variation_7();
|
|
// @cmember Call Abort Again - E_UNEXPECTED
|
|
int Variation_8();
|
|
// @cmember Abort - Invalid Arguments
|
|
int Variation_9();
|
|
// @cmember Advise Listener - after operation is aborted
|
|
int Variation_10();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCAsynchAbort)
|
|
#define THE_CLASS TCAsynchAbort
|
|
BEG_TEST_CASE(TCAsynchAbort, CTestNotify, L"Test Notification Error cases")
|
|
TEST_VARIATION(1, L"Call abort after population completed, verify DB_E_CANTCANCEL")
|
|
TEST_VARIATION(2, L"GetStatus after Abort returns DB_E_CANTCANCEL returns S_OK")
|
|
TEST_VARIATION(3, L"Abort in Initialization phase, Get Status returns DB_E_CANCELED")
|
|
TEST_VARIATION(4, L"call GetStaus twice after Abort - E_UNEXPECTED")
|
|
TEST_VARIATION(5, L"check population is uncomplete after abort called")
|
|
TEST_VARIATION(6, L"Call Abort Again - E_UNEXPECTED")
|
|
TEST_VARIATION(7, L"Call OpenRowset again after Abort")
|
|
TEST_VARIATION(8, L"Call Abort Again - E_UNEXPECTED")
|
|
TEST_VARIATION(9, L"Abort - Invalid Arguments")
|
|
TEST_VARIATION(10, L"Advise Listener - after operation is aborted")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAsynchProperties)
|
|
//*-----------------------------------------------------------------------
|
|
// @class Test all Asynch Properties
|
|
//
|
|
class TCAsynchProperties : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAsynchProperties,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember DBPROP_INIT_ASYNCH - S_OK - Optional
|
|
int Variation_1();
|
|
// @cmember DBPROP_INIT_ASYNCH - S_OK - Required
|
|
int Variation_2();
|
|
// @cmember DBPROP_INIT_ASYNCH - DB_S_ERRORSOCCURRED - Optional
|
|
int Variation_3();
|
|
// @cmember DBPROP_INIT_ASYNCH - DB_E_ERRORSOCCURRED - Required
|
|
int Variation_4();
|
|
// @cmember DBPROP_ROWSET_ASYNCH - S_OK - Optional
|
|
int Variation_5();
|
|
// @cmember DBPROP_ROWSET_ASYNCH - S_OK - Required
|
|
int Variation_6();
|
|
// @cmember DBPROP_ROWSET_ASYNCH - DB_S_ERRORSOCCURRED - Optional
|
|
int Variation_7();
|
|
// @cmember DBPROP_ROWSET_ASYNCH - DB_E_ERRORSOCCURRED - Required
|
|
int Variation_8();
|
|
// }} TCW_TESTVARS_END
|
|
} ;
|
|
// {{ TCW_TESTCASE(TCAsynchProperties)
|
|
#define THE_CLASS TCAsynchProperties
|
|
BEG_TEST_CASE(TCAsynchProperties, CTestNotify, L"Test all Asynch Properties")
|
|
TEST_VARIATION(1, L"DBPROP_INIT_ASYNCH - S_OK - Optional")
|
|
TEST_VARIATION(2, L"DBPROP_INIT_ASYNCH - S_OK - Required")
|
|
TEST_VARIATION(3, L"DBPROP_INIT_ASYNCH - DB_S_ERRORSOCCURRED - Optional")
|
|
TEST_VARIATION(4, L"DBPROP_INIT_ASYNCH - DB_E_ERRORSOCCURRED - Required")
|
|
TEST_VARIATION(5, L"DBPROP_ROWSET_ASYNCH - S_OK - Optional")
|
|
TEST_VARIATION(6, L"DBPROP_ROWSET_ASYNCH - S_OK - Required")
|
|
TEST_VARIATION(7, L"DBPROP_ROWSET_ASYNCH - DB_S_ERRORSOCCURRED - Optional")
|
|
TEST_VARIATION(8, L"DBPROP_ROWSET_ASYNCH - DB_E_ERRORSOCCURRED - Required")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
|
|
// }} END_DECLARE_TEST_CASES()
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Defines
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
#define COPY_TEST_CASE(theClass, baseClass) \
|
|
class theClass : public baseClass \
|
|
{ \
|
|
public: \
|
|
static const WCHAR m_wszTestCaseName[]; \
|
|
DECLARE_TEST_CASE_FUNCS(theClass, baseClass); \
|
|
}; \
|
|
const WCHAR theClass::m_wszTestCaseName[] = { L#theClass }; \
|
|
|
|
|
|
#define TEST_CASE_WITH_PARAM(iCase, theClass, param) \
|
|
case iCase: \
|
|
pCTestCase = new theClass(NULL); \
|
|
((theClass*)pCTestCase)->SetTestCaseParam(param); \
|
|
pCTestCase->SetOwningMod(iCase-1, pCThisTestModule); \
|
|
return pCTestCase;
|
|
|
|
|
|
//TCDataSource
|
|
COPY_TEST_CASE(TCDataSource_AsynchNotify, TCAsynchNotify)
|
|
COPY_TEST_CASE(TCDataSource_AsynchNotifyFailure, TCAsynchNotifyFailure)
|
|
COPY_TEST_CASE(TCDataSource_AsynchStatus, TCAsynchStatus)
|
|
COPY_TEST_CASE(TCDataSource_AsynchAbort, TCAsynchAbort)
|
|
COPY_TEST_CASE(TCDataSource_AsynchProperties, TCAsynchProperties)
|
|
|
|
//TCRow
|
|
COPY_TEST_CASE(TCRow_AsynchNotify, TCAsynchNotify)
|
|
COPY_TEST_CASE(TCRow_AsynchNotifyFailure, TCAsynchNotifyFailure)
|
|
COPY_TEST_CASE(TCRow_AsynchStatus, TCAsynchStatus)
|
|
COPY_TEST_CASE(TCRow_AsynchAbort, TCAsynchAbort)
|
|
COPY_TEST_CASE(TCRow_AsynchProperties, TCAsynchProperties)
|
|
|
|
//TCStream
|
|
COPY_TEST_CASE(TCStream_AsynchNotify, TCAsynchNotify)
|
|
COPY_TEST_CASE(TCStream_AsynchNotifyFailure, TCAsynchNotifyFailure)
|
|
COPY_TEST_CASE(TCStream_AsynchStatus, TCAsynchStatus)
|
|
COPY_TEST_CASE(TCStream_AsynchAbort, TCAsynchAbort)
|
|
COPY_TEST_CASE(TCStream_AsynchProperties, TCAsynchProperties)
|
|
|
|
//TCRowset
|
|
COPY_TEST_CASE(TCRowset_AsynchNotify, TCAsynchNotify)
|
|
COPY_TEST_CASE(TCRowset_AsynchNotifyFailure, TCAsynchNotifyFailure)
|
|
COPY_TEST_CASE(TCRowset_AsynchStatus, TCAsynchStatus)
|
|
COPY_TEST_CASE(TCRowset_AsynchAbort, TCAsynchAbort)
|
|
COPY_TEST_CASE(TCRowset_AsynchProperties, TCAsynchProperties)
|
|
|
|
//TCExecute
|
|
COPY_TEST_CASE(TCExecute_AsynchNotify, TCAsynchNotify)
|
|
COPY_TEST_CASE(TCExecute_AsynchNotifyFailure, TCAsynchNotifyFailure)
|
|
COPY_TEST_CASE(TCExecute_AsynchStatus, TCAsynchStatus)
|
|
COPY_TEST_CASE(TCExecute_AsynchAbort, TCAsynchAbort)
|
|
COPY_TEST_CASE(TCExecute_AsynchProperties, TCAsynchProperties)
|
|
|
|
//TCSchema
|
|
COPY_TEST_CASE(TCSchema_AsynchNotify, TCAsynchNotify)
|
|
COPY_TEST_CASE(TCSchema_AsynchNotifyFailure, TCAsynchNotifyFailure)
|
|
COPY_TEST_CASE(TCSchema_AsynchStatus, TCAsynchStatus)
|
|
COPY_TEST_CASE(TCSchema_AsynchAbort, TCAsynchAbort)
|
|
COPY_TEST_CASE(TCSchema_AsynchProperties, TCAsynchProperties)
|
|
|
|
|
|
//NOTE: The #ifdef block below is only for test wizard. TestWizard has too many
|
|
//strict rules in the parsing code and requires a 1:1 correspondence between
|
|
//testcases and the map. What the #else section is doing is basically "reusing"
|
|
//existing testcases by just passing in a paraemter which changes the behvior.
|
|
//So we make LTM think there are 15 cases in here with different names, but in
|
|
//reality we only have to maintain code for the unique cases. This way we can
|
|
//easily get testing of other storage interfaces, without maintaining 4 different
|
|
//tests with almost identical code...
|
|
|
|
#if 0
|
|
// {{ TCW_TESTMODULE(ThisModule)
|
|
TEST_MODULE(5, ThisModule, gwszModuleDescrip)
|
|
TEST_CASE(1, TCAsynchNotify)
|
|
TEST_CASE(2, TCAsynchNotifyFailure)
|
|
TEST_CASE(3, TCAsynchStatus)
|
|
TEST_CASE(4, TCAsynchAbort)
|
|
TEST_CASE(5, TCAsynchProperties)
|
|
END_TEST_MODULE()
|
|
// }} TCW_TESTMODULE_END
|
|
#else
|
|
TEST_MODULE(30, ThisModule, gwszModuleDescrip)
|
|
//DataSource - IDBAsynchStatus
|
|
TEST_CASE_WITH_PARAM(1, TCDataSource_AsynchNotify, DATASOURCE_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(2, TCDataSource_AsynchNotifyFailure, DATASOURCE_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(3, TCDataSource_AsynchStatus, DATASOURCE_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(4, TCDataSource_AsynchAbort, DATASOURCE_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(5, TCDataSource_AsynchProperties, DATASOURCE_INTERFACE)
|
|
|
|
//Row - IDBAsynchStatus
|
|
TEST_CASE_WITH_PARAM(6, TCRow_AsynchNotify, ROW_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(7, TCRow_AsynchNotifyFailure, ROW_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(8, TCRow_AsynchStatus, ROW_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(9, TCRow_AsynchAbort, ROW_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(10, TCRow_AsynchProperties, ROW_INTERFACE)
|
|
|
|
//Stream - IDBAsynchStatus
|
|
TEST_CASE_WITH_PARAM(11, TCStream_AsynchNotify, STREAM_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(12, TCStream_AsynchNotifyFailure, STREAM_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(13, TCStream_AsynchStatus, STREAM_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(14, TCStream_AsynchAbort, STREAM_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(15, TCStream_AsynchProperties, STREAM_INTERFACE)
|
|
|
|
//Rowset - IDBAsynchStatus
|
|
TEST_CASE_WITH_PARAM(16, TCRowset_AsynchNotify, ROWSET_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(17, TCRowset_AsynchNotifyFailure, ROWSET_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(18, TCRowset_AsynchStatus, ROWSET_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(19, TCRowset_AsynchAbort, ROWSET_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(20, TCRowset_AsynchProperties, ROWSET_INTERFACE)
|
|
|
|
//Rowset - (Command Execute Rowset)
|
|
TEST_CASE_WITH_PARAM(21, TCExecute_AsynchNotify, COMMAND_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(22, TCExecute_AsynchNotifyFailure, COMMAND_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(23, TCExecute_AsynchStatus, COMMAND_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(24, TCExecute_AsynchAbort, COMMAND_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(25, TCExecute_AsynchProperties, COMMAND_INTERFACE)
|
|
|
|
//Rowset - (Schema Rowset)
|
|
TEST_CASE_WITH_PARAM(26, TCSchema_AsynchNotify, ENUMERATOR_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(27, TCSchema_AsynchNotifyFailure, ENUMERATOR_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(28, TCSchema_AsynchStatus, ENUMERATOR_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(29, TCSchema_AsynchAbort, ENUMERATOR_INTERFACE)
|
|
TEST_CASE_WITH_PARAM(30, TCSchema_AsynchProperties, ENUMERATOR_INTERFACE)
|
|
END_TEST_MODULE()
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAsynchNotify)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAsynchNotify - Test Notifications
|
|
//| for notifications
|
|
//| Created: 07/09/97
|
|
//|
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchNotify::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CTestNotify::Init())
|
|
// }}
|
|
{
|
|
return InitSources();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test how many times notified
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_1()
|
|
{
|
|
TBEGIN
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// test listener was not notified for DBASYNCHPHASE_POPULATION and once for all othe phases
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc verify multiple Listeners are advised
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// test listener was not notified for DBASYNCHPHASE_POPULATION and once for all othe phases
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Verify DBASYNCHPHASE_POPULATION is received
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_3()
|
|
{
|
|
TBEGIN
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// test listener was not notified for DBASYNCHPHASE_POPULATION and once for all othe phases
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_4()
|
|
{
|
|
//TBEGIN
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
//TODO
|
|
// TESTC_(pCSource(0)->Initialize(DBPROPVAL_ASYNCH_INITIALIZE | DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION),DB_E_ERRORSOCCURRED);
|
|
|
|
//CLEANUP:
|
|
//WaitUntilComplete();
|
|
//TRETURN
|
|
return TEST_SKIPPED;
|
|
|
|
}
|
|
|
|
// }}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test DBPROPVAL_ASYNCH_RANDOMPOPULATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_5()
|
|
{
|
|
//TBEGIN
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
//TODO
|
|
// TESTC_(pCSource(0)->Initialize(DBPROPVAL_ASYNCH_INITIALIZE | DBPROPVAL_ASYNCH_RANDOMPOPULATION),DB_E_ERRORSOCCURRED);
|
|
|
|
//CLEANUP:
|
|
//WaitUntilComplete();
|
|
//TRETURN
|
|
return TEST_SKIPPED;
|
|
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Test SEQUENTIAL | RANDOM
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_6()
|
|
{
|
|
//TBEGIN
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
//TODO
|
|
// TESTC_(pCSource(0)->Initialize(DBPROPVAL_ASYNCH_INITIALIZE | DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION | DBPROPVAL_ASYNCH_RANDOMPOPULATION),DB_E_ERRORSOCCURRED);
|
|
|
|
//CLEANUP:
|
|
//WaitUntilComplete();
|
|
//TRETURN
|
|
return TEST_SKIPPED;
|
|
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc L1 -OnProgress DB_S_UNWANTEDOPERATION L2, L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_7()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetEvent(DBREASON_ONPROGRESS,DBEVENTPHASE_ALL,FALSE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyEventAll(DBREASON_ONSTOP));
|
|
|
|
// test L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// test L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyUnwantedEvent(pCListener(0), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetEvent(DBREASON_ONPROGRESS,DBEVENTPHASE_ALL,TRUE);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc L1 -OnStop DB_S_UNWANTEDOPERATION L2, L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_8()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetEvent(DBREASON_ONSTOP, DBEVENTPHASE_ALL, FALSE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyEventAll(DBREASON_ONSTOP));
|
|
TESTC(VerifyEventAll(DBREASON_ONPROGRESS));
|
|
|
|
//Cause another set of Notifications, so ONSTOP has another chance to fire
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
TESTC(VerifyUnwantedEvent(pCListener(0), DBREASON_ONSTOP));
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONSTOP));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONSTOP));
|
|
|
|
// testL1 L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyEventAll(DBREASON_ONPROGRESS));
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetEvent(DBREASON_ONSTOP,DBEVENTPHASE_ALL,TRUE);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_9()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetEvent(DBREASON_ONPROGRESS, DBASYNCHPHASE_INITIALIZATION,FALSE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyEventAll(DBREASON_ONSTOP));
|
|
|
|
// testL1 L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyUnwantedEvent(pCListener(0), DBREASON_ONPROGRESS, DBASYNCHPHASE_INITIALIZATION));
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetEvent(DBREASON_ONPROGRESS,DBASYNCHPHASE_INITIALIZATION,TRUE);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_10()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetEvent(DBREASON_ONPROGRESS,DBASYNCHPHASE_POPULATION,FALSE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyEventAll(DBREASON_ONSTOP));
|
|
|
|
// testL1 L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyUnwantedEvent(pCListener(0), DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION));
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetEvent(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION,TRUE);
|
|
UnadviseAll();
|
|
TRETURN
|
|
|
|
}
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc L1 -OnProgress DB_S_UNWANTEDPHASE L2, L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_11()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetEvent(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE, FALSE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyEventAll(DBREASON_ONSTOP));
|
|
|
|
// testL1 L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// testL1 L2, L3 listener was notified with OnProgress
|
|
TESTC(VerifyUnwantedEvent(pCListener(0), DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE));
|
|
TESTC(VerifyEvent(pCListener(1), DBREASON_ONPROGRESS));
|
|
TESTC(VerifyEvent(pCListener(2), DBREASON_ONPROGRESS));
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetEvent(DBREASON_ONPROGRESS,DBASYNCHPHASE_COMPLETE,TRUE);
|
|
UnadviseAll();
|
|
TRETURN
|
|
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc OnLowResource - Veto
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_12()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - OnLowResource - return S_FALSE
|
|
TESTC(pCListener(0)->SetCancel(DBREASON_ONLOWRESOURCE, DBASYNCHPHASE_COMPLETE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//Should never be notified of OnLowResource()
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONLOWRESOURCE, DBASYNCHPHASE_COMPLETE) == 0);
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetCancel(-1, -1);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc OnStop - Veto
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_13()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - OnStop - return S_FALSE
|
|
TESTC(pCListener(0)->SetCancel(DBREASON_ONSTOP, DBASYNCHPHASE_COMPLETE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//S_FALSE from OnStop should not affect anything - not vetoable notification
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetCancel(-1, -1);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc OnProgress - Veto CANCELED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_14()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
// L1 - OnProgress - return S_FALSE
|
|
TESTC(pCListener(0)->SetCancel(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
|
|
//Try calling IDBAsyncStatus::Abort() which will fire OnProgress(CANCELED)
|
|
hr = pCSource(0)->Abort();
|
|
TEST3C_(hr, S_OK, DB_E_CANCELED, DB_E_CANTCANCEL);
|
|
|
|
if(hr==DB_E_CANTCANCEL || !pCSource(0)->IsAsynch())
|
|
{
|
|
TWARNING("Unable to Abort operation, not Asynch or CANTCANCEL?");
|
|
//Wait until complete
|
|
TESTC_(WaitUntilComplete(), S_OK);
|
|
TESTC(VerifyAllConnections());
|
|
}
|
|
else
|
|
{
|
|
//Make sure the listener was notified of the cancel
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED) == 1);
|
|
|
|
//Wait until complete
|
|
TESTC_(WaitUntilComplete(), S_OK);
|
|
TESTC(VerifyAllConnections(hr==S_OK ? OP_ABORTED : OP_ABORTED|OP_COMPLETED));
|
|
}
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetCancel(-1, -1);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc OnProgress - Veto INITIALIZATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_15()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
// L1 - OnProgress - return S_FALSE
|
|
TESTC(pCListener(0)->SetCancel(DBREASON_ONPROGRESS, DBASYNCHPHASE_INITIALIZATION));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
|
|
//Try to veto OnProgress(INITIALIZATION)
|
|
hr = pCSource(0)->GetStatus();
|
|
TESTC(hr==S_OK || hr==DB_E_CANCELED)
|
|
|
|
if(hr==DB_E_CANCELED)
|
|
{
|
|
//Verify Listeners were given the chance to Veto
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_INITIALIZATION)>=1);
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED)>=1);
|
|
|
|
//Should have all normal notifications and status
|
|
TESTC_(WaitUntilComplete(), S_OK);
|
|
TESTC(VerifyAllConnections(OP_ABORTED));
|
|
}
|
|
else
|
|
{
|
|
//Otherwise Listeners were not given a chance to Veto
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_INITIALIZATION)==0);
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED)==0);
|
|
TWARNING("Unable to veto DBASYNCHPHASE_INITIALIZATION?");
|
|
|
|
//Should have all normal notifications and status
|
|
TESTC_(WaitUntilComplete(), S_OK);
|
|
TESTC(VerifyAllConnections());
|
|
}
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetCancel(-1, -1);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc OnProgress - Veto POPULATION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_16()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
|
|
// L1 - OnProgress - return S_FALSE
|
|
TESTC(pCListener(0)->SetCancel(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
|
|
//Try to veto OnProgress(POPULATION)
|
|
hr = pCSource(0)->GetStatus();
|
|
TESTC(hr==S_OK || hr==DB_E_CANCELED)
|
|
|
|
if(hr==DB_E_CANCELED)
|
|
{
|
|
//Verify Listeners were given the chance to Veto
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION)>=1);
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED)>=1);
|
|
|
|
//Should have all normal notifications and status
|
|
TESTC_(WaitUntilComplete(), S_OK);
|
|
TESTC(VerifyAllConnections(OP_ABORTED));
|
|
}
|
|
else
|
|
{
|
|
//Otherwise Listeners were not given a chance to Veto
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_POPULATION)==0);
|
|
TESTC(pCListener(0)->GetTimesNotified(DBREASON_ONPROGRESS, DBASYNCHPHASE_CANCELED)==0);
|
|
TWARNING("Unable to veto DBASYNCHPHASE_POPULATION?");
|
|
|
|
//Should have all normal notifications and status
|
|
TESTC_(WaitUntilComplete(), S_OK);
|
|
TESTC(VerifyAllConnections());
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetCancel(-1, -1);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc OnProgress - Veto COMPLETE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_17()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - OnProgress - return S_FALSE
|
|
TESTC(pCListener(0)->SetCancel(DBREASON_ONPROGRESS, DBASYNCHPHASE_COMPLETE));
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//S_FALSE from OnProgress(COMPLETE) should not affect anything - not vetoable notification
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetCancel(-1, -1);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Advise Listener - after operation is complete
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotify::Variation_18()
|
|
{
|
|
TBEGIN
|
|
ULONG iSource = 0;
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
|
|
//Wait until the operation is complete...
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//Reset all listeners. This is becuase we want to make sure none of the other
|
|
//listeners that are already advised receive any notifications
|
|
TESTC(ResetListeners());
|
|
UnadviseAll();
|
|
|
|
//Now advise listeners, after the fact.
|
|
//Spec requires that all newly advised listeners that "missed" the operation
|
|
//be notified that the operation already completed. This is becuase at least for the rowset
|
|
//you may not be able to get the listeners advised quickly enough before the operation is complete.
|
|
//As oppsoed to the datasource where you can advise listeners first and then when everything
|
|
//is all hooked up then Initialize can be called...
|
|
for(iSource=0; iSource<m_vectSources.GetCount(); iSource++)
|
|
{
|
|
//Advise this listener to this source...
|
|
TESTC(Advise(pCListener(0), pCSource(iSource)));
|
|
|
|
//Make sure it was notified of OnProgress(COMPLETE) and OnStop().
|
|
//Make sure no other Listeners were notified
|
|
TESTC(VerifyAllConnections(OP_COMPLETED));
|
|
}
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchNotify::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAsynchNotifyFailure)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAsynchNotifyFailure - Test Notification Error cases
|
|
//| Created: 07/10/97
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchNotifyFailure::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CTestNotify::Init())
|
|
// }}
|
|
{
|
|
return InitSources();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - L1 , L1, L2 , L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotifyFailure::Variation_1()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetError(E_FAIL))
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// test L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetError(S_OK);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - L1 L2 , L1, L2 , L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotifyFailure::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetError(E_FAIL))
|
|
TESTC(pCListener(1)->SetError(E_FAIL))
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// test L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetError(S_OK);
|
|
pCListener(1)->SetError(S_OK);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - L1 L2 , L1, L2 , L3 receive all phases
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotifyFailure::Variation_3()
|
|
{
|
|
|
|
TBEGIN
|
|
|
|
// L1 - return DB_S_UNWANTEDOPERATION
|
|
TESTC(pCListener(0)->SetError(E_FAIL))
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(AdviseAll());
|
|
|
|
//Wait until Complete
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
// test L2, L3 listener was notified once for OnStop
|
|
TESTC(VerifyAllConnections());
|
|
|
|
CLEANUP:
|
|
pCListener(0)->SetError(S_OK);
|
|
pCListener(1)->SetError(S_OK);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetLocate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotifyFailure::Variation_4()
|
|
{
|
|
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetResynch
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotifyFailure::Variation_5()
|
|
{
|
|
|
|
return TEST_SKIPPED;
|
|
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetScroll
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchNotifyFailure::Variation_6()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchNotifyFailure::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAsynchStatus)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAsynchStatus - Test Notification Error cases
|
|
//| for notifications
|
|
//| Created: 07/09/97
|
|
//|
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchStatus::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CTestNotify::Init())
|
|
// }}
|
|
{
|
|
return InitSources();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Check the HRESULT from GetStatus
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchStatus::Variation_1()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Verify ProgressMax == ProgressCurr
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchStatus::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//test that progressmaxCurr == progresscurr
|
|
TESTC(pCSource(0)->GetProgress() == pCSource(0)->GetProgressMax());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc check ulAsynchPhase is DBASYNCHPHASE_COMPLETE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchStatus::Variation_3()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//test that progressmaxCurr == progresscurr
|
|
TESTC(pCSource(0)->GetProgress() == pCSource(0)->GetProgressMax());
|
|
TESTC(pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_COMPLETE);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Verify ratio corresponds to returned staus code
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchStatus::Variation_4()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
TESTC(pCSource(0)->GetProgress() < pCSource(0)->GetProgressMax());
|
|
}
|
|
else
|
|
{
|
|
TESTC(pCSource(0)->GetProgress() == pCSource(0)->GetProgressMax());
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Verify ratio of ProgressCurr and ProgressMax
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchStatus::Variation_5()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
TESTC(pCSource(0)->GetPrevProgress() <= pCSource(0)->GetProgress());
|
|
TESTC(pCSource(0)->GetPrevProgressMax() <= pCSource(0)->GetProgressMax());
|
|
}
|
|
else
|
|
{
|
|
TESTC(pCSource(0)->GetProgress() == pCSource(0)->GetProgressMax());
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Poll for status continuously
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchStatus::Variation_6()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
|
|
// poll for status
|
|
while ( !pCSource(0)->IsComplete())
|
|
{
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
TESTC(pCSource(0)->GetPrevProgress() <= pCSource(0)->GetProgress());
|
|
TESTC(pCSource(0)->GetPrevProgressMax() <= pCSource(0)->GetProgressMax());
|
|
}
|
|
else
|
|
{
|
|
TESTC(pCSource(0)->GetProgress() == pCSource(0)->GetProgressMax());
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchStatus::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAsynchAbort)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAsynchAbort - Test Notification Error cases
|
|
//| for notifications
|
|
//| Created: 07/09/97
|
|
//|
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchAbort::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CTestNotify::Init())
|
|
// }}
|
|
{
|
|
return InitSources();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call abort after population completed, verify DB_E_CANTCANCEL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_1()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
TESTC_(pCSource(0)->Abort(), S_OK);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc GetStatus after Abort returns DB_E_CANTCANCEL returns S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
TESTC_(pCSource(0)->Abort(), S_OK);
|
|
|
|
// call getstaus returns S_OK
|
|
TESTC_(pCSource(0)->GetStatus(), S_OK);
|
|
TESTC(pCSource(0)->GetProgress() == pCSource(0)->GetProgressMax());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort in Initialization phase, Get Status returns DB_E_CANCELED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_3()
|
|
{
|
|
TBEGIN
|
|
TESTC(InitSources());
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
TESTC(pCSource(0)->VerifyAbort());
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc call GetStaus twice after Abort - E_UNEXPECTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_4()
|
|
{
|
|
TBEGIN
|
|
TESTC(InitSources());
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
//Abort
|
|
TESTC(pCSource(0)->VerifyAbort());
|
|
}
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc check population is uncomplete after abort called
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_5()
|
|
{
|
|
TBEGIN
|
|
TESTC(InitSources());
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
TESTC(pCSource(0)->VerifyAbort());
|
|
|
|
// call getstaus again
|
|
TESTC(pCSource(0)->GetProgress() < pCSource(0)->GetProgressMax());
|
|
}
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call Abort Again - E_UNEXPECTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_6()
|
|
{
|
|
TBEGIN
|
|
TESTC(InitSources());
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
TESTC(pCSource(0)->VerifyAbort());
|
|
}
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call OpenRowset again after Abort
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_7()
|
|
{
|
|
TBEGIN
|
|
TESTC(InitSources());
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
if( pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_INITIALIZATION ||
|
|
pCSource(0)->GetAsynchPhase() == DBASYNCHPHASE_POPULATION)
|
|
{
|
|
TESTC(pCSource(0)->VerifyAbort());
|
|
}
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC_(pCSource(0)->GetStatus(),S_OK);
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Call Abort Again - E_UNEXPECTED
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_8()
|
|
{
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Abort - Invalid Arguments
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_9()
|
|
{
|
|
TBEGIN
|
|
TESTC(InitSources());
|
|
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
|
|
//GetStatus - InvalidArg (acording to spec this is S_OK)
|
|
TESTC_(pCSource(0)->GetStatus(INVALID(ULONG)),S_OK);
|
|
|
|
//Abort - InvalidArg - (according to spec this is S_OK)
|
|
TESTC_(pCSource(0)->Abort(INVALID(ULONG)),S_OK);
|
|
|
|
CLEANUP:
|
|
WaitUntilComplete();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Advise Listener - after operation is aborted
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchAbort::Variation_10()
|
|
{
|
|
TBEGIN
|
|
ULONG iSource = 0;
|
|
HRESULT hr = S_OK;
|
|
ULONG iListener = 0;
|
|
//Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
|
|
//Try aborting the operation
|
|
hr = pCSource(0)->Abort();
|
|
TEST3C_(hr, S_OK, DB_E_CANCELED, DB_E_CANTCANCEL);
|
|
|
|
//Wait until the operation is complete...
|
|
WaitUntilComplete();
|
|
UnadviseAll();
|
|
|
|
//Now advise listeners, after the fact.
|
|
//Spec requires that all newly advised listeners that "missed" the operation
|
|
//be notified that the operation already completed. This is becuase at least for the rowset
|
|
//you may not be able to get the listeners advised quickly enough before the operation is complete.
|
|
//As oppsoed to the datasource where you can advise listeners first and then when everything
|
|
//is all hooked up then Initialize can be called...
|
|
for(iSource=0; iSource<m_vectSources.GetCount(); iSource++)
|
|
{
|
|
BOOL fAborted = (iSource==0 && hr==S_OK && pCSource(0)->IsAsynch());
|
|
|
|
//Reset all listeners. This is becuase we want to make sure none of the other
|
|
//listeners that are already advised receive any notifications
|
|
TESTC(ResetListeners());
|
|
|
|
//Advise this listener to this source...
|
|
TESTC(Advise(pCListener(0), pCSource(iSource)));
|
|
|
|
//Make sure it was notified of OnProgress(CANCELED) and OnStop().
|
|
//Make sure no other Listeners were notified
|
|
for(iListener=0; iListener<m_vectListeners.GetCount(); iListener++)
|
|
{
|
|
TESTC(VerifyConnection(pCListener(iListener), pCSource(iSource), fAborted ? OP_ABORTED : OP_COMPLETED, fAborted ? ULONG_MAX : 0));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchAbort::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAsynchProperties)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAsynchProperties - Test all Asynch Properties
|
|
//| Created: 5/6/98
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAsynchProperties::Init()
|
|
{
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(CTestNotify::Init())
|
|
// }}
|
|
{
|
|
return InitSources();
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_INIT_ASYNCH - S_OK - Optional
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_1()
|
|
{
|
|
TBEGIN
|
|
CDataSource DataSourceA;
|
|
IDBAsynchStatus *pIDBAsynchStatus = NULL;
|
|
ULONG ulAsynchPhase = 0;
|
|
ULONG_PTR ulAsynch = 0;
|
|
|
|
//Variation only applies for datasource
|
|
if (pCSource(0)->GetObjectType() != DATASOURCE_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for DataSource");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
DataSourceA.CreateInstance();
|
|
|
|
//Set the property
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
|
|
//Property errors - DB_S_ERRORSOCCURRED
|
|
QI(DataSourceA.pIDBInit(), IID_IDBAsynchStatus, (void**)&pIDBAsynchStatus);
|
|
switch (DataSourceA.Initialize())
|
|
{
|
|
case DB_S_ERRORSOCCURRED:
|
|
TESTC(!SupportedProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT) || !SettableProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT));
|
|
break;
|
|
case DB_S_ASYNCHRONOUS:
|
|
TESTC(pIDBAsynchStatus!=NULL);
|
|
while(TRUE)
|
|
{
|
|
//IDBAsynchStatus::GetStatus
|
|
TESTC_(pIDBAsynchStatus->GetStatus(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN, NULL, NULL, &ulAsynchPhase, NULL), S_OK);
|
|
|
|
//Check for an error in the provider
|
|
TESTC(DBASYNCHPHASE_INITIALIZATION==ulAsynchPhase || DBASYNCHPHASE_COMPLETE==ulAsynchPhase)
|
|
|
|
//As soon as we have S_OK and COMPLETE we are done...
|
|
if(ulAsynchPhase==DBASYNCHPHASE_COMPLETE)
|
|
break;
|
|
|
|
//Sleep a little, so we don't have such a tight loop...
|
|
Sleep(100);
|
|
}
|
|
TESTC(GetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, pIDBAsynchStatus, &ulAsynch));
|
|
TESTC(DBPROPVAL_ASYNCH_INITIALIZE==ulAsynch);
|
|
break;
|
|
case S_OK:
|
|
//TO DO: may be should compare ulAsynch with 0?
|
|
TWARNING("IDBInitialize::Initialize returned S_OK, is the DataSource created Immediatly?");
|
|
TESTC(GetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, pIDBAsynchStatus, &ulAsynch));
|
|
TESTC(DBPROPVAL_ASYNCH_INITIALIZE==ulAsynch);
|
|
break;
|
|
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBAsynchStatus);
|
|
DataSourceA.Uninitialize();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_INIT_ASYNCH - S_OK - Required
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_2()
|
|
{
|
|
TBEGIN
|
|
ULONG_PTR ulAsynch = 0;
|
|
|
|
//Variation only applies for datasource
|
|
if (pCSource(0)->GetObjectType() != DATASOURCE_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for DataSource");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
|
|
//Wait until Complete
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//DBPROP_ROWSET_ASYNCH
|
|
TESTC(GetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, pCSource(0)->pIDBAsynchStatus(), &ulAsynch));
|
|
|
|
if(pCSource(0)->IsAsynch())
|
|
{
|
|
TESTC(ulAsynch == DBPROPVAL_ASYNCH_INITIALIZE);
|
|
TESTC(SettableProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT));
|
|
}
|
|
else
|
|
{
|
|
TESTC(ulAsynch == 0);
|
|
TESTC(SupportedProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT));
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_INIT_ASYNCH - DB_S_ERRORSOCCURRED - Optional
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_3()
|
|
{
|
|
// TO DO: Add your own code here
|
|
CDataSource DataSourceA;
|
|
|
|
//Variation only applies for datasource
|
|
if (pCSource(0)->GetObjectType() != DATASOURCE_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for DataSource");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
DataSourceA.CreateInstance();
|
|
|
|
//NOTSUPPORTED (wrong propset)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DATASOURCEINFO, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADVALUE (wrong type DBTYPE_BOOL)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADVALUE (wrong value DBTYPE_I2)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I2, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADVALUE (wrong value)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)(ULONG_PTR)INVALID(DWORD), DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADOPTION(wrong value)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)PROPVAL_NEGATIVE, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
|
|
//Property errors - DB_S_ERRORSOCCURRED
|
|
TESTC_(DataSourceA.Initialize(), DB_S_ERRORSOCCURRED);
|
|
|
|
//Verify error array
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[0].rgProperties[0].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[0].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[1].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[2].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[3].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
|
|
CLEANUP:
|
|
DataSourceA.Uninitialize();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_INIT_ASYNCH - DB_E_ERRORSOCCURRED - Required
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_4()
|
|
{
|
|
// TO DO: Add your own code here
|
|
CDataSource DataSourceA;
|
|
|
|
//Variation only applies for datasource
|
|
if (pCSource(0)->GetObjectType() != DATASOURCE_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for DataSource");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
DataSourceA.CreateInstance();
|
|
|
|
//NOTSUPPORTED (wrong propset)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DATASOURCEINFO, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I4, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
//BADVALUE (wrong type DBTYPE_BOOL)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_BOOL, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
//BADVALUE (wrong value DBTYPE_I2)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I2, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
//BADVALUE (wrong value)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)(ULONG_PTR)INVALID(DWORD), DBTYPE_I4, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
//BADOPTION(wrong value)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)PROPVAL_NEGATIVE, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADOPTION(wrong value)
|
|
DataSourceA.SetProperty(DBPROP_INIT_ASYNCH, DBPROPSET_DBINIT, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I4, INVALID(DBPROPOPTIONS), DB_NULLID);
|
|
|
|
//Property errors - DB_E_ERRORSOCCURRED
|
|
TESTC_(DataSourceA.Initialize(), DB_E_ERRORSOCCURRED);
|
|
|
|
//Verify error array
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[0].rgProperties[0].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[0].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[1].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[2].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[3].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(DataSourceA.m_rgPropSets[1].rgProperties[4].dwStatus == DBPROPSTATUS_BADOPTION);
|
|
|
|
CLEANUP:
|
|
DataSourceA.Uninitialize();
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_ROWSET_ASYNCH - S_OK - Optional
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_5()
|
|
{
|
|
TBEGIN
|
|
|
|
ULONG_PTR ulAsynch = 0;
|
|
ULONG ulAsynchPhase = 0;
|
|
HRESULT hr = 0;
|
|
IDBAsynchStatus *pIDBAsynchStatus = NULL;
|
|
COpenRowset OpenRowsetA;
|
|
|
|
//Variation only applies for rowsets
|
|
if (pCSource(0)->GetObjectType() != ROWSET_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for Rowset");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)(DBPROPVAL_ASYNCH_INITIALIZE | DBPROPVAL_ASYNCH_RANDOMPOPULATION | DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION), DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
|
|
hr = OpenRowsetA.CreateOpenRowset(IID_IDBAsynchStatus, (IUnknown**)&pIDBAsynchStatus);
|
|
|
|
switch (hr)
|
|
{
|
|
case DB_S_ERRORSOCCURRED:
|
|
TESTC(!SupportedProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET) || !SettableProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET));
|
|
break;
|
|
case DB_S_ASYNCHRONOUS:
|
|
TESTC(pIDBAsynchStatus!=NULL);
|
|
while(TRUE)
|
|
{
|
|
//IDBAsynchStatus::GetStatus
|
|
TESTC_(pIDBAsynchStatus->GetStatus(DB_NULL_HCHAPTER, DBASYNCHOP_OPEN, NULL, NULL, &ulAsynchPhase, NULL), S_OK);
|
|
|
|
//Check for an error in the provider
|
|
TESTC(DBASYNCHPHASE_INITIALIZATION==ulAsynchPhase || DBASYNCHPHASE_COMPLETE==ulAsynchPhase || DBASYNCHPHASE_POPULATION==ulAsynchPhase)
|
|
|
|
//As soon as we have S_OK and COMPLETE we are done...
|
|
if(ulAsynchPhase==DBASYNCHPHASE_COMPLETE)
|
|
break;
|
|
|
|
//Sleep a little, so we don't have such a tight loop...
|
|
Sleep(100);
|
|
}
|
|
TESTC(GetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, pIDBAsynchStatus, &ulAsynch));
|
|
TESTC(ulAsynch & (DBASYNCHPHASE_INITIALIZATION==ulAsynchPhase || DBASYNCHPHASE_COMPLETE==ulAsynchPhase || DBASYNCHPHASE_POPULATION==ulAsynchPhase));
|
|
break;
|
|
case S_OK:
|
|
//TO DO: may be we should compare ulAsynch with 0 in this case?
|
|
TWARNING("Rowset creation returned S_OK, is the rowset was created Immediatly?");
|
|
TESTC(GetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, pIDBAsynchStatus, &ulAsynch));
|
|
TESTC(ulAsynch & (DBASYNCHPHASE_INITIALIZATION==ulAsynchPhase || DBASYNCHPHASE_COMPLETE==ulAsynchPhase || DBASYNCHPHASE_POPULATION==ulAsynchPhase));
|
|
break;
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIDBAsynchStatus);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_ROWSET_ASYNCH - S_OK - Required
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_6()
|
|
{
|
|
TBEGIN
|
|
ULONG_PTR ulAsynch = 0;
|
|
|
|
//Variation only applies for rowsets
|
|
if (pCSource(0)->GetObjectType() != ROWSET_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for Rowset");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
// Reset DataSource and Advise Listeners
|
|
TESTC(ResetSources());
|
|
TESTC(CauseNotifications());
|
|
|
|
//Wait until Complete
|
|
TESTC_(WaitUntilComplete(),S_OK);
|
|
|
|
//DBPROP_ROWSET_ASYNCH
|
|
TESTC(GetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, pCSource(0)->pIDBAsynchStatus(), &ulAsynch));
|
|
|
|
if(pCSource(0)->IsAsynch())
|
|
{
|
|
TESTC(ulAsynch & DBPROPVAL_ASYNCH_INITIALIZE);
|
|
TESTC(SettableProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET));
|
|
}
|
|
else
|
|
{
|
|
TESTC(ulAsynch == 0);
|
|
TESTC(SupportedProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET));
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_ROWSET_ASYNCH - DB_S_ERRORSOCCURRED - Optional
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_7()
|
|
{
|
|
COpenRowset OpenRowsetA;
|
|
IRowset* pIRowset = NULL;
|
|
|
|
//Variation only applies for rowsets
|
|
if (pCSource(0)->GetObjectType() != ROWSET_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for Rowset");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
//NOTSUPPORTED (wrong propset)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSETALL, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADVALUE (wrong type)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I2, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADVALUE (wrong type)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADVALUE (wrong value)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)(ULONG_PTR)INVALID(DWORD), DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//BADVALUE (wrong value)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)PROPVAL_NEGATIVE, DBTYPE_I4, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
|
|
//Property errors - DB_S_ERRORSOCCURRED
|
|
TESTC_(OpenRowsetA.CreateOpenRowset(IID_IUnknown, (IUnknown**)&pIRowset), DB_S_ERRORSOCCURRED);
|
|
TESTC(pIRowset != NULL);
|
|
|
|
//Verify error array
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[0].rgProperties[0].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[1].rgProperties[0].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[1].rgProperties[1].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[1].rgProperties[2].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[1].rgProperties[3].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowset);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc DBPROP_ROWSET_ASYNCH - DB_E_ERRORSOCCURRED - Required
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAsynchProperties::Variation_8()
|
|
{
|
|
COpenRowset OpenRowsetA;
|
|
IRowset* pIRowset = NULL;
|
|
|
|
//Variation only applies for rowsets
|
|
if (pCSource(0)->GetObjectType() != ROWSET_INTERFACE)
|
|
{
|
|
TOUTPUT_LINE(L"The variation runs only for Rowset");
|
|
return TEST_SKIPPED;
|
|
};
|
|
|
|
//NOTSUPPORTED (wrong propset)
|
|
OpenRowsetA.SetProperty(DBPROP_CANHOLDROWS, DBPROPSET_ROWSETALL, (void*)VARIANT_TRUE, DBTYPE_BOOL, DBPROPOPTIONS_OPTIONAL, DB_NULLID);
|
|
//NOTSUPPORTED (wrong propset)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSETALL, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I4, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
//BADVALUE (wrong type)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I2, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
//BADVALUE (wrong value)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)(ULONG_PTR)INVALID(DWORD), DBTYPE_I4, DBPROPOPTIONS_REQUIRED, DB_NULLID);
|
|
//BADOPTION(wrong value)
|
|
OpenRowsetA.SetProperty(DBPROP_ROWSET_ASYNCH, DBPROPSET_ROWSET, (void*)DBPROPVAL_ASYNCH_INITIALIZE, DBTYPE_I4, INVALID(DBPROPOPTIONS), DB_NULLID);
|
|
|
|
//Property errors - DB_E_ERRORSOCCURRED
|
|
TESTC_(OpenRowsetA.CreateOpenRowset(IID_IUnknown, (IUnknown**)&pIRowset), DB_E_ERRORSOCCURRED);
|
|
TESTC(pIRowset == NULL);
|
|
|
|
//Verify error array
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[0].rgProperties[0].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[0].rgProperties[1].dwStatus == DBPROPSTATUS_NOTSUPPORTED);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[1].rgProperties[0].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[1].rgProperties[1].dwStatus == DBPROPSTATUS_BADVALUE);
|
|
TCOMPARE_(OpenRowsetA.m_rgPropSets[1].rgProperties[2].dwStatus == DBPROPSTATUS_BADOPTION);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowset);
|
|
TRETURN
|
|
}
|
|
// }} TCW_VAR_PROTOTYPE_END
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
BOOL TCAsynchProperties::Terminate()
|
|
{
|
|
// TO DO: Add your own code here
|
|
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }} TCW_TERMINATE_METHOD_END
|
|
// }} TCW_TC_PROTOTYPE_END
|
|
|