//-------------------------------------------------------------------- // 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; iFindConnectionPoint(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_vectListeners; //array of Listeners //Associated (Multiple) Source CVector m_vectSources; //array of Sources //Track connections between sources and listeners CList 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; iCreateSource()) } CLEANUP: TRETURN } BOOL CTestNotify::ResetSources(DWORD dwPropVal) { TBEGIN ULONG i = 0; //Reset all listeners ResetListeners(); //Reset all Sources for(i=0; iResetSource(dwPropVal)); CLEANUP: TRETURN } BOOL CTestNotify::ResetListeners() { TBEGIN ULONG i = 0; //Reset all listeners for(i=0; iResetTimesNotified()); 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; iListenerm_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; iResetTimesNotified()); //verify listener recieved notification for(i=0; iCauseNotification()); 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; iWaitUntilComplete(),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; iListenerGetTimesNotified() == 0); } CLEANUP: TRETURN } BOOL CTestNotify::VerifyEventAll(DBASYNCHREASON eReason, DBASYNCHPHASE ePhase) { TBEGIN ULONG i = 0; for(i=0; iIsAsynch()) 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; iIsAsynch()) 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; iSourceSetError(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; iSourceIsAsynch()); //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; iListenerGetObjectType() != 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