7829 lines
221 KiB
C++
7829 lines
221 KiB
C++
//--------------------------------------------------------------------
|
|
// Microsoft OLE DB Test
|
|
//
|
|
// Copyright (C) 1995-2000 Microsoft Corporation
|
|
//
|
|
// @doc
|
|
//
|
|
// @module ICPoint.cpp | This test module performs testing of IConnectionPoint interface
|
|
//
|
|
|
|
#include "MODStandard.hpp" // Standard headers to be precompiled in MODStandard.cpp
|
|
#include "ICPoint.h"
|
|
#include "ExtraLib.h"
|
|
#include "olectl.h" //CONNECT_E_NOCONNECT
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
// Module Values
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
// {{ TCW_MODULE_GLOBALS
|
|
DECLARE_MODULE_CLSID = { 0xe1b56244, 0x6bfb, 0x11cf, { 0xaa, 0x20, 0x00, 0xaa, 0x00, 0x3e, 0x77, 0x8a }};
|
|
DECLARE_MODULE_NAME("IConnectionPoint");
|
|
DECLARE_MODULE_OWNER("Microsoft");
|
|
DECLARE_MODULE_DESCRIP("IConnectionPoint test");
|
|
DECLARE_MODULE_VERSION(838751865);
|
|
// TCW_WizardVersion(2)
|
|
// TCW_Automation(True)
|
|
// }} TCW_MODULE_GLOBALS_END
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Forwards
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class CSource;
|
|
class CListener;
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Constants
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
const int MAX_CP_ON_SOURCE = 2;
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Defines
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
#define INVALID_PUNK INVALID(IUnknown*)
|
|
#define INVALID_COOKIE INVALID(DWORD)
|
|
|
|
|
|
//--------------------------------------------------------------------
|
|
// @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_IConnectionPointContainer, ROWSET_INTERFACE) ||
|
|
SupportedInterface(IID_IConnectionPointContainer, ROW_INTERFACE) ||
|
|
SupportedInterface(IID_IConnectionPointContainer, 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);
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func BOOL|
|
|
// VerifyEqualICPoint
|
|
// Check if connection points are the same
|
|
//--------------------------------------------------------------------
|
|
BOOL VerifyEqualICPoint(IConnectionPoint *pICP1, IConnectionPoint *pICP2)
|
|
{
|
|
TBEGIN;
|
|
|
|
HRESULT hr1 = S_OK;
|
|
HRESULT hr2 = S_OK;
|
|
HRESULT hr = S_OK;
|
|
|
|
IID iid1 = IID_NULL;
|
|
IID iid2 = IID_NULL;
|
|
|
|
IEnumConnections *pIEnumC1 = NULL;
|
|
IEnumConnections *pIEnumC2 = NULL;
|
|
|
|
DWORD dwCookie = 0;
|
|
CListener* pListener = NULL;
|
|
CONNECTDATA rgConnectData[2] = { {NULL, 0}, {NULL, 0} };
|
|
|
|
// if Objects match by IUnknown no more verification nedded
|
|
if (VerifyEqualInterface(pICP1, pICP2))
|
|
return TRUE;
|
|
|
|
// Verify connection interface
|
|
hr1 = pICP1->GetConnectionInterface(&iid1);
|
|
hr2 = pICP2->GetConnectionInterface(&iid2);
|
|
TESTC(hr1==hr2 && iid1==iid2);
|
|
|
|
pListener = new CListener(IID_IUnknown);
|
|
SAFE_ADDREF(pListener);
|
|
|
|
// Verify Advise/Unadvise
|
|
hr = pICP1->Advise(pListener, &dwCookie);
|
|
|
|
// Verify that both CP contains the same listeners
|
|
hr1 = pICP1->EnumConnections(&pIEnumC1);
|
|
hr2 = pICP2->EnumConnections(&pIEnumC2);
|
|
|
|
if (!VerifyEqualInterface(pIEnumC1, pIEnumC2))
|
|
{
|
|
ULONG cFetched1 = 0;
|
|
ULONG cFetched2 = 0;
|
|
for (ULONG i=1; i<7; i++)
|
|
{
|
|
hr1 = pIEnumC1->Next(1, &rgConnectData[0], &cFetched1);
|
|
hr2 = pIEnumC2->Next(1, &rgConnectData[1], &cFetched2);
|
|
TESTC(hr1==hr2 && cFetched1==cFetched2 &&
|
|
rgConnectData[0].dwCookie == rgConnectData[1].dwCookie &&
|
|
rgConnectData[0].pUnk == rgConnectData[1].pUnk);
|
|
SAFE_RELEASE(rgConnectData[0].pUnk);
|
|
SAFE_RELEASE(rgConnectData[1].pUnk);
|
|
rgConnectData[0].dwCookie = 0;
|
|
rgConnectData[1].dwCookie = 0;
|
|
}
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
if (SUCCEEDED(hr))
|
|
TESTC_(pICP2->Unadvise(dwCookie), S_OK);
|
|
SAFE_RELEASE(rgConnectData[0].pUnk);
|
|
SAFE_RELEASE(rgConnectData[1].pUnk);
|
|
SAFE_RELEASE(pListener);
|
|
SAFE_RELEASE(pIEnumC1);
|
|
SAFE_RELEASE(pIEnumC2);
|
|
TRETURN
|
|
}
|
|
|
|
//--------------------------------------------------------------------
|
|
// @func BOOL|
|
|
// VerifyEqualICPC
|
|
// Check if connection point containers are the same
|
|
//--------------------------------------------------------------------
|
|
BOOL VerifyEqualICPC(IConnectionPointContainer *pICPC1, IConnectionPointContainer *pICPC2)
|
|
{
|
|
TBEGIN;
|
|
|
|
HRESULT hr1 = S_OK;
|
|
HRESULT hr2 = S_OK;
|
|
|
|
IConnectionPoint *pCPoint1 = NULL;
|
|
IConnectionPoint *pCPoint2 = NULL;
|
|
|
|
IID rgIIDs[3];
|
|
|
|
// All possible connection points
|
|
rgIIDs[0] = IID_IRowsetNotify;
|
|
rgIIDs[1] = IID_IDBAsynchNotify;
|
|
rgIIDs[2] = IID_IRowPositionChange;
|
|
|
|
if (VerifyEqualInterface(pICPC1, pICPC2))
|
|
return TRUE;
|
|
|
|
// Ferify consistency in connection points
|
|
for (ULONG i = 0; i<3; i++)
|
|
{
|
|
hr1 = pICPC1->FindConnectionPoint(rgIIDs[i], &pCPoint1);
|
|
hr2 = pICPC2->FindConnectionPoint(rgIIDs[i], &pCPoint2);
|
|
TESTC(hr1==hr2);
|
|
TESTC(VerifyEqualICPoint(pCPoint1, pCPoint2));
|
|
SAFE_RELEASE(pCPoint1);
|
|
SAFE_RELEASE(pCPoint2);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pCPoint1);
|
|
SAFE_RELEASE(pCPoint2);
|
|
TRETURN
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// 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;
|
|
virtual BOOL IsOptionalCP(REFIID riid) = 0;
|
|
virtual BOOL IsSupportedCP(REFIID riid);
|
|
|
|
//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;
|
|
//m_rgSupportedCP array contains CP that can be found through FindConnectionPoint and EnumConnectionPoints
|
|
IID m_rgSupportedCP[MAX_CP_ON_SOURCE];
|
|
ULONG m_cSupportedCP;
|
|
|
|
};
|
|
|
|
|
|
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;
|
|
|
|
//Valid CP
|
|
for (ULONG i=0; i<MAX_CP_ON_SOURCE; i++)
|
|
{
|
|
m_rgSupportedCP[i] = IID_NULL;
|
|
}
|
|
m_cSupportedCP = 0;
|
|
|
|
}
|
|
|
|
CSource::~CSource()
|
|
{
|
|
ReleaseCP();
|
|
}
|
|
|
|
BOOL CSource::IsSupportedCP(REFIID riid)
|
|
{
|
|
for (ULONG i=0; i<m_cSupportedCP; i++)
|
|
{
|
|
if (riid == m_rgSupportedCP[i])
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CSource::ReleaseCP()
|
|
{
|
|
//Container
|
|
SAFE_RELEASE(m_pIConnectionPointContainer);
|
|
SAFE_RELEASE(m_pIEnumConnectionPoints);
|
|
|
|
//Connection Points
|
|
for(ULONG i=0; i<m_cConnectionPoints; i++)
|
|
SAFE_RELEASE(m_rgConnectionPoints[i]);
|
|
SAFE_FREE(m_rgConnectionPoints);
|
|
m_cConnectionPoints = 0;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CSource::CreateCP(IUnknown* pIUnknown)
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 0;
|
|
IConnectionPoint* pICP = NULL;
|
|
IConnectionPoint* pICP2 = NULL;
|
|
BOOL fFindCP = FALSE;
|
|
IID iid;
|
|
|
|
//Obtain the connection point container
|
|
QTESTC_((QI(pIUnknown, IID_IConnectionPointContainer, (void**)&m_pIConnectionPointContainer)),S_OK);
|
|
|
|
//NOTE:
|
|
//If IConnectionPointContainer is exposed by the Source we need to test it (at least run TCEnumConnectionPoints)
|
|
//to be sure that there are no wrong CPs on the source => commented out
|
|
|
|
//Make sure this connection supports the connection point were interested in...
|
|
//QTESTC_(m_pIConnectionPointContainer->FindConnectionPoint(m_iid, &pICP),S_OK);
|
|
//SAFE_RELEASE(pICP);
|
|
|
|
//Obtain the IEnumConnectionPoints
|
|
TESTC_(m_pIConnectionPointContainer->EnumConnectionPoints(&m_pIEnumConnectionPoints),S_OK);
|
|
TESTC(m_pIEnumConnectionPoints != NULL)
|
|
|
|
//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);
|
|
|
|
|
|
//if iid of pICP is not yet in the array of Supported CP and it's optional for this Source
|
|
//and we can find it through FindConnectionPoint => add it to the array of Supported CP (we will test it)
|
|
if (S_OK==pICP->GetConnectionInterface(&iid) && IsOptionalCP(iid) && !IsSupportedCP(iid) &&
|
|
S_OK==m_pIConnectionPointContainer->FindConnectionPoint(iid, &pICP2) && pICP2)
|
|
{
|
|
m_rgSupportedCP[m_cSupportedCP++] = iid;
|
|
}
|
|
SAFE_RELEASE(pICP2);
|
|
|
|
//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 && !fFindCP)
|
|
{
|
|
m_rgConnectionPoints[m_cConnectionPoints] = m_rgConnectionPoints[0];
|
|
m_rgConnectionPoints[0] = pICP;
|
|
fFindCP = 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:
|
|
TRETURN;
|
|
}
|
|
|
|
BOOL CSource::VerifyNotification(CListener* pCListener, ULONG ulTimesConnected)
|
|
{
|
|
ASSERT(pCListener);
|
|
TBEGIN
|
|
|
|
TESTC(pCListener->GetTimesNotified() >= ulTimesConnected);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynchDSOSource
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynchDSOSource : public CSource, public CDataSource
|
|
{
|
|
public:
|
|
//Constructors
|
|
CAsynchDSOSource(WCHAR* pwszTestCaseName = INVALID(WCHAR*));
|
|
virtual ~CAsynchDSOSource();
|
|
|
|
//pure virtual members (defined)
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL CauseNotification();
|
|
virtual int IsOptionalCP(REFIID riid) {return IID_IDBAsynchNotify==riid;};
|
|
|
|
|
|
//Helpers
|
|
virtual BOOL VerifyNotification(CListener* pCListener, ULONG ulTimesConnected);
|
|
|
|
protected:
|
|
};
|
|
|
|
|
|
CAsynchDSOSource::CAsynchDSOSource(WCHAR* pwszTestCaseName)
|
|
: CDataSource((LPWSTR)pwszTestCaseName), CSource(IID_IDBAsynchNotify, DATASOURCE_INTERFACE)
|
|
{
|
|
}
|
|
|
|
CAsynchDSOSource::~CAsynchDSOSource()
|
|
{
|
|
}
|
|
|
|
|
|
BOOL CAsynchDSOSource::CreateSource()
|
|
{
|
|
TBEGIN
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//Create an Instance first, so we can hook up out listeners,
|
|
//before any notifications
|
|
TESTC_(hr = CDataSource::CreateInstance(),S_OK);
|
|
|
|
//Now that we have our object, just call the baseclass to obtain all the connection pointers...
|
|
QTESTC(CreateCP(m_pIDBInitialize));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CAsynchDSOSource::CauseNotification()
|
|
{
|
|
TBEGIN
|
|
|
|
//Cause a notification to occur
|
|
//TODO
|
|
//CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchDSOSource::VerifyNotification(CListener* pCListener, ULONG ulTimesConnected)
|
|
{
|
|
ASSERT(pCListener);
|
|
TBEGIN
|
|
|
|
//TODO
|
|
// TESTC(pCListener->GetTimesNotified() >= ulTimesConnected);
|
|
|
|
//CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CRowsetSource
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CRowsetSource : public CSource, public CRowset
|
|
{
|
|
public:
|
|
//Constructors
|
|
CRowsetSource(REFIID riid = IID_IRowsetNotify, WCHAR* pwszTestCaseName = INVALID(WCHAR*));
|
|
virtual ~CRowsetSource();
|
|
|
|
//pure virtual members (defined)
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL CauseNotification();
|
|
virtual int IsOptionalCP(REFIID riid) {return IID_IRowsetNotify==riid || IID_IDBAsynchNotify==riid;};
|
|
|
|
//Helpers
|
|
virtual BOOL VerifyNotification(CListener* pCListener, ULONG ulTimesConnected);
|
|
protected:
|
|
};
|
|
|
|
|
|
CRowsetSource::CRowsetSource(REFIID riid, WCHAR* pwszTestCaseName)
|
|
: CRowset((LPWSTR)pwszTestCaseName), CSource(riid, ROWSET_INTERFACE)
|
|
{
|
|
}
|
|
|
|
CRowsetSource::~CRowsetSource()
|
|
{
|
|
}
|
|
|
|
|
|
BOOL CRowsetSource::CreateSource()
|
|
{
|
|
TBEGIN
|
|
|
|
//If ICPC is not supported, were done testing!
|
|
//Create the rowset asking for IID_IConnectionPointContainer, same as
|
|
//explicitly setting the property DBPROP_IConnectionPointContainer
|
|
SetProperty(DBPROP_CANHOLDROWS);
|
|
QTESTC_(CreateRowset(USE_SUPPORTED_SELECT_ALLFROMTBL, IID_IConnectionPointContainer),S_OK);
|
|
|
|
//Now that we have our object, just call the baseclass to obtain all the connection pointers...
|
|
QTESTC(CreateCP(pIRowset()));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CRowsetSource::CauseNotification()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = NULL;
|
|
|
|
//Cause a notification to occur DBREASON_ROW_ACTIVATE
|
|
TESTC_(GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
CLEANUP:
|
|
//Release row and cause closing notification DBREASON_ROW_RELEASE
|
|
ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CRowsetSource::VerifyNotification(CListener* pCListener, ULONG ulTimesConnected)
|
|
{
|
|
ASSERT(pCListener);
|
|
TBEGIN
|
|
|
|
//CauseNotification only causes notification for IrowsetNotify
|
|
//IDBAsynchNotify is tested in the IDBAsynch Test
|
|
if (IID_IRowsetNotify==GetIID())
|
|
{
|
|
TESTC(pCListener->GetTimesNotified() >= ulTimesConnected);
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynchRowSource
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynchRowSource : public CSource, public CRowObject
|
|
{
|
|
public:
|
|
//Constructors
|
|
CAsynchRowSource(WCHAR* pwszTestCaseName = INVALID(WCHAR*));
|
|
virtual ~CAsynchRowSource();
|
|
|
|
//pure virtual members (defined)
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL CauseNotification();
|
|
virtual int IsOptionalCP(REFIID riid) {return IID_IDBAsynchNotify==riid;};
|
|
|
|
//Helpers
|
|
virtual BOOL VerifyNotification(CListener* pCListener, ULONG ulTimesConnected);
|
|
|
|
protected:
|
|
};
|
|
|
|
|
|
CAsynchRowSource::CAsynchRowSource(WCHAR* pwszTestCaseName)
|
|
: CSource(IID_IDBAsynchNotify, ROW_INTERFACE)
|
|
{
|
|
}
|
|
|
|
CAsynchRowSource::~CAsynchRowSource()
|
|
{
|
|
}
|
|
|
|
|
|
BOOL CAsynchRowSource::CreateSource()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
IRow* pIRow = NULL;
|
|
|
|
//Create a row object
|
|
//Row Objects are optional behavior...
|
|
TEST3C_(hr = g_pTable->CreateRowset(USE_OPENROWSET, 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 CAsynchRowSource::CauseNotification()
|
|
{
|
|
TBEGIN
|
|
|
|
//Cause a notification to occur
|
|
//TODO
|
|
//CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchRowSource::VerifyNotification(CListener* pCListener, ULONG ulTimesConnected)
|
|
{
|
|
ASSERT(pCListener);
|
|
TBEGIN
|
|
|
|
//TODO
|
|
// TESTC(pCListener->GetTimesNotified() >= ulTimesConnected);
|
|
|
|
//CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// class CAsynchStreamSource
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
class CAsynchStreamSource : public CSource, public CRowObject
|
|
{
|
|
public:
|
|
//Constructors
|
|
CAsynchStreamSource(WCHAR* pwszTestCaseName = INVALID(WCHAR*));
|
|
virtual ~CAsynchStreamSource();
|
|
|
|
//pure virtual members (defined)
|
|
virtual BOOL CreateSource();
|
|
virtual BOOL CauseNotification();
|
|
virtual int IsOptionalCP(REFIID riid) {return IID_IDBAsynchNotify==riid;};
|
|
|
|
//Helpers
|
|
virtual BOOL VerifyNotification(CListener* pCListener, ULONG ulTimesConnected);
|
|
|
|
protected:
|
|
};
|
|
|
|
|
|
CAsynchStreamSource::CAsynchStreamSource(WCHAR* pwszTestCaseName)
|
|
: CSource(IID_IDBAsynchNotify, STREAM_INTERFACE)
|
|
{
|
|
}
|
|
|
|
CAsynchStreamSource::~CAsynchStreamSource()
|
|
{
|
|
}
|
|
|
|
|
|
BOOL CAsynchStreamSource::CreateSource()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
IRow* pIRow = NULL;
|
|
IUnknown* pIUnknown = NULL;
|
|
ULONG iCol=0;
|
|
|
|
//Create a row object
|
|
//Row Objects are optional behavior...
|
|
TEST3C_(hr = g_pTable->CreateRowset(USE_OPENROWSET, 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);
|
|
}
|
|
|
|
//Now that we have a row object, dump it into our helper CRowObject class...
|
|
TESTC_(SetRowObject(pIRow),S_OK);
|
|
|
|
//See if we can obtain a stream object over any of the columns...
|
|
for(iCol=0; iCol<m_cColAccess; iCol++)
|
|
{
|
|
//Open will mainly only be able to be called for columns containing objects.
|
|
//But some providers might be able to open streams, or other types of objects ontop
|
|
//of non-object valued columns.
|
|
hr = Open(NULL, &m_rgColAccess[iCol].columnid, DBGUID_STREAM, IID_IUnknown, &pIUnknown);
|
|
TEST3C_(hr, S_OK, S_FALSE, DB_E_OBJECTMISMATCH);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//We need at least one stream that supports connection points
|
|
if(CreateCP(pIUnknown))
|
|
break;
|
|
}
|
|
|
|
SAFE_RELEASE(pIUnknown);
|
|
}
|
|
|
|
//At this point we should a stream object, that supports connection points
|
|
QTESTC(pIUnknown != NULL);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIUnknown);
|
|
SAFE_RELEASE(pIRow);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CAsynchStreamSource::CauseNotification()
|
|
{
|
|
TBEGIN
|
|
|
|
//Cause a notification to occur
|
|
//TODO
|
|
//CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CAsynchStreamSource::VerifyNotification(CListener* pCListener, ULONG ulTimesConnected)
|
|
{
|
|
ASSERT(pCListener);
|
|
TBEGIN
|
|
|
|
//TODO
|
|
// TESTC(pCListener->GetTimesNotified() >= ulTimesConnected);
|
|
|
|
//CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCBase
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class TCBase
|
|
{
|
|
public:
|
|
//constructor
|
|
TCBase()
|
|
{
|
|
m_dwTestCaseParam1 = UNKNOWN_INTERFACE;
|
|
m_dwTestCaseParam2 = IID_NULL;
|
|
}
|
|
|
|
//methods
|
|
virtual void SetTestCaseParams(EINTERFACE dwTestCaseParam1, REFIID dwTestCaseParam2 = IID_IDBAsynchNotify)
|
|
{
|
|
m_dwTestCaseParam1 = dwTestCaseParam1;
|
|
m_dwTestCaseParam2 = dwTestCaseParam2;
|
|
}
|
|
|
|
//data
|
|
EINTERFACE m_dwTestCaseParam1;
|
|
IID m_dwTestCaseParam2;
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// TCTransaction
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
class TCTransaction : public CTransaction, public TCBase
|
|
{
|
|
public:
|
|
//constructors
|
|
TCTransaction(WCHAR* pwszTestCaseName = INVALID(WCHAR*)) : CTransaction(pwszTestCaseName) {}
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
// Class CTestNotify
|
|
//
|
|
// Manages testing between Source(s) (containers) and Sink(s) (listeners)
|
|
//////////////////////////////////////////////////////////////////
|
|
class CTestNotify : public COLEDB, public TCBase
|
|
{
|
|
public:
|
|
//contsructor
|
|
CTestNotify(WCHAR* pwszTestCaseName);
|
|
virtual ~CTestNotify();
|
|
|
|
//members
|
|
virtual BOOL Init();
|
|
virtual BOOL Terminate();
|
|
|
|
//Thread Function
|
|
static ULONG WINAPI Thread_AdviseListener(LPVOID pv);
|
|
|
|
//helper
|
|
virtual ULONG VerifyRefCount();
|
|
virtual BOOL VerifyUniqueCookie(DWORD dwCookie, CSource* pCSource);
|
|
|
|
//Connections
|
|
virtual BOOL VerifyNoConnection();
|
|
virtual BOOL VerifyNoConnection(CListener* pCListener, CSource* pCSource);
|
|
virtual BOOL VerifyConnection(CListener* pCListener, CSource* pCSource, ULONG ulTimesConnected = ULONG_MAX);
|
|
virtual BOOL VerifyConnectData(ULONG cConnectData, CONNECTDATA* rgConnectData, ULONG cCookies, DWORD* rgCookies);
|
|
virtual BOOL VerifyConnectionPoints(ULONG cConnectionPoints, IConnectionPoint** rgpIConnectionPoints);
|
|
virtual BOOL FreeConnectionPoints(ULONG cConnectionPoints, IConnectionPoint** rgpIConnectionPoints);
|
|
|
|
//Advise connections
|
|
virtual BOOL Advise(CListener* pCListener, CSource* pCSource, DWORD* pdwCookie = NULL);
|
|
virtual BOOL AdviseNum(ULONG cListeners, ULONG cSources, DWORD* const rgCookie = NULL);
|
|
|
|
//Unadvise Connections
|
|
virtual BOOL UnadviseAll();
|
|
virtual BOOL Unadvise(CListener* pCListener, CSource* pCSource);
|
|
|
|
//Indexing
|
|
virtual CListener* pCListener(ULONG iListener) { return m_vectListeners[iListener]; }
|
|
virtual CSource* pCSource(ULONG iSource) { return m_vectSources[iSource]; }
|
|
|
|
protected:
|
|
//data
|
|
BOOL m_fInitRefCounts;
|
|
|
|
//Associated (Multiple) Listeners
|
|
CVector<CListener*> m_vectListeners; //array of Listeners
|
|
|
|
//Associated (Multiple) Rowsets
|
|
CVector<CSource*> m_vectSources; //array of Sources
|
|
|
|
//Track connections between sources and listeners
|
|
CList<CConnectInfo*, CConnectInfo*> m_listConnectInfo;
|
|
CRITICAL_SECTION ConnTableMutex;
|
|
};
|
|
|
|
|
|
CTestNotify::CTestNotify(WCHAR* pwszTestCaseName) : COLEDB(pwszTestCaseName)
|
|
{
|
|
//Data
|
|
m_fInitRefCounts = FALSE;
|
|
}
|
|
|
|
CTestNotify::~CTestNotify()
|
|
{
|
|
//Free the list of connection info
|
|
while(!m_listConnectInfo.IsEmpty())
|
|
{
|
|
CConnectInfo* pCConnectInfo = m_listConnectInfo.RemoveHead();
|
|
SAFE_DELETE(pCConnectInfo);
|
|
}
|
|
}
|
|
|
|
|
|
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 Sources
|
|
for(i=0; i<6; i++)
|
|
{
|
|
CSource* pCSource = NULL;
|
|
|
|
//First 2 sources have the possibility of being row sources
|
|
switch(m_dwTestCaseParam1)
|
|
{
|
|
case ROWSET_INTERFACE:
|
|
pCSource = new CRowsetSource(m_dwTestCaseParam2);
|
|
break;
|
|
|
|
case DATASOURCE_INTERFACE:
|
|
pCSource = new CAsynchDSOSource;
|
|
break;
|
|
|
|
case ROW_INTERFACE:
|
|
pCSource = new CAsynchRowSource;
|
|
break;
|
|
|
|
case STREAM_INTERFACE:
|
|
pCSource = new CAsynchStreamSource;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(!L"Unhandled TestCase Type!");
|
|
break;
|
|
};
|
|
|
|
//Initialize the source
|
|
TESTC(pCSource != NULL);
|
|
|
|
//Add this source to the list...
|
|
m_vectSources.AddElement(pCSource);
|
|
TESTC_PROVIDER(pCSource->CreateSource())
|
|
|
|
}
|
|
|
|
//Init Listeners
|
|
for(i=0; i<5; i++)
|
|
{
|
|
//Default listener
|
|
CListener* pCListener = new CListener;
|
|
TESTC(pCListener != NULL);
|
|
|
|
//Add this listener to the list...
|
|
pCListener->AddRef();
|
|
m_vectListeners.AddElement(pCListener);
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::Terminate()
|
|
{
|
|
ULONG i=0;
|
|
//Free the list of Sources
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
SAFE_DELETE(m_vectSources[i]);
|
|
m_vectSources.RemoveAll();
|
|
|
|
//Free the list of listeners
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
{
|
|
//Make sure their are no outstanding references on the listeners...
|
|
SAFE_RELEASE_(m_vectListeners[i]);
|
|
}
|
|
m_vectListeners.RemoveAll();
|
|
|
|
DeleteCriticalSection(&ConnTableMutex);
|
|
return COLEDB::Terminate();
|
|
}
|
|
|
|
|
|
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, pCSource));
|
|
|
|
//Verify refcount is greater after advise
|
|
TESTC(VerifyRefCounts(GetRefCount(pCListener), cRefCount+1));
|
|
|
|
CLEANUP:
|
|
if(pdwCookie)
|
|
*pdwCookie = dwCookie;
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CTestNotify::AdviseNum(ULONG cListeners, ULONG cSources, DWORD* const rgdwCookies)
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise the specified number of connections, and verify
|
|
for(ULONG iListener=0, index=0; iListener<cListeners; iListener++)
|
|
{
|
|
for(ULONG iSource=0; iSource<cSources; iSource++, index++)
|
|
{
|
|
TESTC(Advise(pCListener(iListener), pCSource(iSource), rgdwCookies ? &rgdwCookies[index] : NULL));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
ULONG CTestNotify::VerifyRefCount()
|
|
{
|
|
TBEGIN
|
|
static ULONG RC_Listener[1000];
|
|
static ULONG RC_rgpICPC[1000];
|
|
static ULONG RC_pIConnectionPoint[1000];
|
|
static ULONG RC_pEnumCP[1000];
|
|
ULONG i=0;
|
|
//1 time intialization
|
|
if(!m_fInitRefCounts)
|
|
{
|
|
//Now Initalized
|
|
m_fInitRefCounts = TRUE;
|
|
|
|
//Initalize RefCount values at init
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
RC_Listener[i] = GetRefCount(pCListener(i));
|
|
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
{
|
|
RC_rgpICPC[i] = GetRefCount(pCSource(i)->pICPC());
|
|
RC_pIConnectionPoint[i] = GetRefCount(pCSource(i)->GetCP());
|
|
RC_pEnumCP[i] = GetRefCount(pCSource(i)->pIEnumCP());
|
|
}
|
|
}
|
|
|
|
//Verify only 1 reference to each sink, (our 1 pointer from this object)
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
TESTC(GetRefCount(pCListener(i)) == RC_Listener[i]);
|
|
|
|
//Verify only 1 reference to each rowset
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
{
|
|
//Verify only 1 connection to the CPC
|
|
TESTC(GetRefCount(pCSource(i)->pICPC()) == RC_rgpICPC[i]);
|
|
|
|
//Verify only 1 connection to the CP
|
|
TESTC(GetRefCount(pCSource(i)->GetCP()) ==RC_pIConnectionPoint[i]);
|
|
|
|
//Verify only 1 connection to the EnumCP
|
|
TESTC(GetRefCount(pCSource(i)->pIEnumCP()) == RC_pEnumCP[i]);
|
|
}
|
|
|
|
CLEANUP:
|
|
//Adjust values, so all following variations don't bomb
|
|
for(i=0; i<m_vectListeners.GetCount(); i++)
|
|
RC_Listener[i] = GetRefCount(pCListener(i));
|
|
|
|
for(i=0; i<m_vectSources.GetCount(); i++)
|
|
{
|
|
RC_rgpICPC[i] = GetRefCount(pCSource(i)->pICPC());
|
|
RC_pIConnectionPoint[i] = GetRefCount(pCSource(i)->GetCP());
|
|
RC_pEnumCP[i] = GetRefCount(pCSource(i)->pIEnumCP());
|
|
}
|
|
|
|
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 no connection, or correct numerber of connections left
|
|
TESTC(VerifyConnection(pCListener, pCSource));
|
|
TESTC(VerifyRefCounts(GetRefCount(pCListener), cRefCount-1));
|
|
break;
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::UnadviseAll()
|
|
{
|
|
TBEGIN
|
|
|
|
//Unadvise all Cookies in the list
|
|
//NOTE: Unadvise will remove the element from the list so we can
|
|
//just loop until either the list is empty or an error occurs
|
|
while(!m_listConnectInfo.IsEmpty())
|
|
{
|
|
CConnectInfo* pCConnectInfo = m_listConnectInfo.GetHead();
|
|
TESTC(Unadvise(pCConnectInfo->m_pCListener, pCConnectInfo->m_pCSource));
|
|
}
|
|
|
|
//Verify no connection
|
|
TESTC(VerifyNoConnection());
|
|
|
|
//Verify reference count
|
|
TESTC(VerifyRefCount());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Thread routines - IConnectionPoint
|
|
//
|
|
///////////////////////////////////////////////////////////
|
|
|
|
ULONG CTestNotify::Thread_AdviseListener(LPVOID pv)
|
|
{
|
|
THREAD_BEGIN
|
|
|
|
//Thread Stack Variables
|
|
IUnknown* pIUnknown = (IUnknown*)THREAD_FUNC;
|
|
ASSERT(pIUnknown);
|
|
|
|
//"new" is not thread safe!
|
|
EnterCriticalSection(&GlobalMutex);
|
|
|
|
//Local Variables
|
|
IConnectionPoint* pICP = NULL;
|
|
IConnectionPointContainer* pICPC = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Instantiate a listener object, within this thread
|
|
CListener* pCListener = new CListener(*(IID*)THREAD_ARG1);//(IID_IRowsetNotify);
|
|
TESTC(pCListener!=NULL);
|
|
pCListener->AddRef();
|
|
|
|
//Obtain the connection point container
|
|
TESTC_(pIUnknown->QueryInterface(IID_IConnectionPointContainer,(void **)&pICPC),S_OK);
|
|
//Obtain the IRowsetNotify connection point
|
|
TESTC_(pICPC->FindConnectionPoint(*(IID*)THREAD_ARG1,&pICP),S_OK);//(IID_IRowsetNotify,&pICP),S_OK);
|
|
|
|
ThreadSwitch(); //Let the other thread(s) catch up
|
|
|
|
//Now we can advise the connection from the rowset->pICP to the listener in this thread
|
|
TESTC_(pICP->Advise(pCListener, &dwCookie),S_OK);
|
|
|
|
//We need to stall, so that we give enough time for the rowset in the main
|
|
//thread to generate a notification, so that we pick it up before
|
|
//closing/unadvising this connection
|
|
Sleep(2000); //Sleep for a couple of seconds, (milliseconds)
|
|
|
|
//Now should have recieved the notification by now...
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
CLEANUP:
|
|
//Unadvise the connection to the listener
|
|
if(pICP)
|
|
pICP->Unadvise(dwCookie);
|
|
|
|
SAFE_RELEASE(pCListener);
|
|
SAFE_RELEASE(pICP);
|
|
SAFE_RELEASE(pICPC);
|
|
|
|
LeaveCriticalSection(&GlobalMutex);
|
|
|
|
THREAD_RETURN
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::VerifyNoConnection()
|
|
{
|
|
TBEGIN
|
|
ULONG iListener, iSource;
|
|
|
|
//reset all listeners
|
|
for(iListener=0; iListener<m_vectListeners.GetCount(); iListener++)
|
|
TESTC(pCListener(iListener)->ResetTimesNotified());
|
|
|
|
//cause the source to notify the listener
|
|
for(iSource=0; iSource<m_vectSources.GetCount(); iSource++)
|
|
TESTC(pCSource(iSource)->CauseNotification());
|
|
|
|
//verify listener recieved notification
|
|
for(iListener=0; iListener<m_vectListeners.GetCount(); iListener++)
|
|
TESTC(pCListener(iListener)->GetTimesNotified() == 0);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CTestNotify::VerifyNoConnection(CListener* pCListener, CSource* pCSource)
|
|
{
|
|
return VerifyConnection(pCListener, pCSource, 0);
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::VerifyConnection(CListener* pCListener, CSource* pCSource, 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 && pCSource == pCConnectInfo->m_pCSource)
|
|
ulTimesConnected++;
|
|
}
|
|
}
|
|
|
|
//reset listener's notify count
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
|
|
//cause the source to notify the listener
|
|
TESTC(pCSource->CauseNotification());
|
|
|
|
//verify listener recieved notification
|
|
TESTC(pCSource->VerifyNotification(pCListener, ulTimesConnected));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
BOOL CTestNotify::VerifyConnectData(ULONG cConnectData, CONNECTDATA* rgConnectData, ULONG cCookies, DWORD* rgCookies)
|
|
{
|
|
//Need to verify rgConnectData array contains the correct information
|
|
//NOTE: rgConnectData doesn't have to be ordered direclty with the order
|
|
//that the connections were established.
|
|
ULONG ulFound = 0;
|
|
|
|
//Loop over the ConnectData
|
|
for(ULONG i=0; i<cConnectData; i++)
|
|
{
|
|
//Must at least be in the valid range for Sink/Cookie!
|
|
if(rgConnectData[i].pUnk == NULL || rgConnectData[i].dwCookie == 0)
|
|
return FALSE;
|
|
|
|
//Try to find the cookie in the list of cookies.
|
|
//Once the cookie is found, lookup the corresponding listener
|
|
for(ULONG j=0; j<cCookies; j++)
|
|
{
|
|
if(rgConnectData[i].dwCookie==rgCookies[j])
|
|
{
|
|
if(!VerifyEqualInterface(rgConnectData[i].pUnk, pCListener(j)))
|
|
return FALSE;
|
|
|
|
ulFound++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return ulFound == cConnectData;
|
|
}
|
|
|
|
BOOL CTestNotify::FreeConnectionPoints(ULONG cConnectionPoints, IConnectionPoint** rgpIConnectionPoints)
|
|
{
|
|
for(ULONG i=0; i<cConnectionPoints; i++)
|
|
{
|
|
SAFE_RELEASE(rgpIConnectionPoints[i]);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CTestNotify::VerifyConnectionPoints(ULONG cConnectionPoints, IConnectionPoint** rgpIConnectionPoints)
|
|
{
|
|
TBEGIN
|
|
ULONG i;
|
|
|
|
//Sanity Check
|
|
TESTC(cConnectionPoints <= pCSource(0)->GetCountCP());
|
|
|
|
//Loop over connections and verify
|
|
for(i=0; i<cConnectionPoints; i++)
|
|
{
|
|
//Sanity Check
|
|
TESTC(rgpIConnectionPoints!=NULL && rgpIConnectionPoints[i]!= NULL);
|
|
|
|
IID iid;
|
|
TESTC_(rgpIConnectionPoints[i]->GetConnectionInterface(&iid),S_OK);
|
|
|
|
//Make sure their is only 1 occurance of each connection point...
|
|
for(ULONG iPrev=0; iPrev<i; iPrev++)
|
|
{
|
|
IID iidPrev;
|
|
TESTC_(rgpIConnectionPoints[iPrev]->GetConnectionInterface(&iidPrev),S_OK);
|
|
TESTC(iid != iidPrev);
|
|
}
|
|
|
|
if(!pCSource(0)->IsOptionalCP(iid))
|
|
{
|
|
TWARNING("Container supports unrecognized Connection Points?" << GetInterfaceName(iid));
|
|
}
|
|
}
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCAdvise)
|
|
//--------------------------------------------------------------------
|
|
// @class Test IConnectionPoint::Advise(
|
|
//
|
|
class TCAdvise : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCAdvise,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - verify reference count
|
|
int Variation_1();
|
|
// @cmember Boundary/NULL - [null, valid] - E_POINTER
|
|
int Variation_2();
|
|
// @cmember Boundary/NULL - [valid, null] - E_POINTER
|
|
int Variation_3();
|
|
// @cmember Boundary/NULL - [invalid sink, valid] - CANNOTCONNECT
|
|
int Variation_4();
|
|
// @cmember Boundary/NULL - Max connections+1 | 20 connections
|
|
int Variation_5();
|
|
// @cmember Usage Context - valid call, (IID_IRowsetNotify with a notify sink
|
|
int Variation_6();
|
|
// @cmember Usage Context - 3 valid calls, (IID_IRowsetNotify with a notify sink
|
|
int Variation_7();
|
|
// @cmember Usage Context - invalid call, (IID_ISomeOther with a notify sink
|
|
int Variation_8();
|
|
// @cmember Usage Context - valid / invalvid / valid calls
|
|
int Variation_9();
|
|
// @cmember Multi-Threaded - 2 Sinks / 1 Sources (Sep Threads
|
|
int Variation_10();
|
|
// @cmember Multi-Threaded - 2 Sinks / 3 Sources (Sep Threads
|
|
int Variation_11();
|
|
// @cmember Multi-Threaded - 2 Sinks / 1 Source (Sep DB Sessions
|
|
int Variation_12();
|
|
// @cmember Multi-Threaded - 2 Sinks / 3 Source (Sep DB Sessions
|
|
int Variation_13();
|
|
// @cmember Multi-User - 1 Sink / 1 Source
|
|
int Variation_14();
|
|
// @cmember Multi-User - 2 Sinks / 1 Source
|
|
int Variation_15();
|
|
// @cmember Multi-User - 1 Sink / 3 Sources
|
|
int Variation_16();
|
|
// @cmember Multi-User - 2 Sinks / 3 Sources
|
|
int Variation_17();
|
|
// @cmember RefCount - Release of Rowset
|
|
int Variation_18();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCAdvise)
|
|
#define THE_CLASS TCAdvise
|
|
BEG_TEST_CASE(TCAdvise, CTestNotify, L"Test IConnectionPoint::Advise(")
|
|
TEST_VARIATION(1, L"General - verify reference count")
|
|
TEST_VARIATION(2, L"Boundary/NULL - [null, valid] - E_POINTER")
|
|
TEST_VARIATION(3, L"Boundary/NULL - [valid, null] - E_POINTER")
|
|
TEST_VARIATION(4, L"Boundary/NULL - [invalid sink, valid] - CANNOTCONNECT")
|
|
TEST_VARIATION(5, L"Boundary/NULL - Max connections+1 | 20 connections")
|
|
TEST_VARIATION(6, L"Usage Context - valid call, (IID_IRowsetNotify with a notify sink")
|
|
TEST_VARIATION(7, L"Usage Context - 3 valid calls, (IID_IRowsetNotify with a notify sink")
|
|
TEST_VARIATION(8, L"Usage Context - invalid call, (IID_ISomeOther with a notify sink")
|
|
TEST_VARIATION(9, L"Usage Context - valid / invalvid / valid calls")
|
|
TEST_VARIATION(10, L"Multi-Threaded - 2 Sinks / 1 Sources (Sep Threads")
|
|
TEST_VARIATION(11, L"Multi-Threaded - 2 Sinks / 3 Sources (Sep Threads")
|
|
TEST_VARIATION(12, L"Multi-Threaded - 2 Sinks / 1 Source (Sep DB Sessions")
|
|
TEST_VARIATION(13, L"Multi-Threaded - 2 Sinks / 3 Source (Sep DB Sessions")
|
|
TEST_VARIATION(14, L"Multi-User - 1 Sink / 1 Source")
|
|
TEST_VARIATION(15, L"Multi-User - 2 Sinks / 1 Source")
|
|
TEST_VARIATION(16, L"Multi-User - 1 Sink / 3 Sources")
|
|
TEST_VARIATION(17, L"Multi-User - 2 Sinks / 3 Sources")
|
|
TEST_VARIATION(18, L"RefCount - Release of Rowset")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCUnadvise)
|
|
//--------------------------------------------------------------------
|
|
// @class Test IConnectionPoint::Unadvise(
|
|
//
|
|
class TCUnadvise : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCUnadvise,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - verify reference count
|
|
int Variation_1();
|
|
// @cmember Boundary/NULL - [null] - NOCONNECTION
|
|
int Variation_2();
|
|
// @cmember Boundary/NULL - Unadvise before any Advises
|
|
int Variation_3();
|
|
// @cmember Sequence - Advise/Unadivse 12 variations
|
|
int Variation_4();
|
|
// @cmember Transactions - Enabled
|
|
int Variation_5();
|
|
// @cmember Transactions - Disabled
|
|
int Variation_6();
|
|
// @cmember Multi-Threaed - 1 Sink / 3 Sources (Sep Threads
|
|
int Variation_7();
|
|
// @cmember Multi-Threaed - 3 Sinks / 3 Sources (Sep Threads
|
|
int Variation_8();
|
|
// @cmember Multi-Threaed - 1 Sink / 3 Sources (Sep DB Sessions
|
|
int Variation_9();
|
|
// @cmember Multi-Threaed - 3 Sinks / 3 Sources (Sep DB Sessions
|
|
int Variation_10();
|
|
// @cmember Multi-User - 1 Sink / 1 Source
|
|
int Variation_11();
|
|
// @cmember Multi-User - 3 Sinks / 1 Source
|
|
int Variation_12();
|
|
// @cmember Multi-User - 1 Sink / 3 Sources
|
|
int Variation_13();
|
|
// @cmember Multi-User - 3 Sinks / 3 Sources
|
|
int Variation_14();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCUnadvise)
|
|
#define THE_CLASS TCUnadvise
|
|
BEG_TEST_CASE(TCUnadvise, CTestNotify, L"Test IConnectionPoint::Unadvise(")
|
|
TEST_VARIATION(1, L"General - verify reference count")
|
|
TEST_VARIATION(2, L"Boundary/NULL - [null] - NOCONNECTION")
|
|
TEST_VARIATION(3, L"Boundary/NULL - Unadvise before any Advises")
|
|
TEST_VARIATION(4, L"Sequence - Advise/Unadivse 12 variations")
|
|
TEST_VARIATION(5, L"Transactions - Enabled")
|
|
TEST_VARIATION(6, L"Transactions - Disabled")
|
|
TEST_VARIATION(7, L"Multi-Threaed - 1 Sink / 3 Sources (Sep Threads")
|
|
TEST_VARIATION(8, L"Multi-Threaed - 3 Sinks / 3 Sources (Sep Threads")
|
|
TEST_VARIATION(9, L"Multi-Threaed - 1 Sink / 3 Sources (Sep DB Sessions")
|
|
TEST_VARIATION(10, L"Multi-Threaed - 3 Sinks / 3 Sources (Sep DB Sessions")
|
|
TEST_VARIATION(11, L"Multi-User - 1 Sink / 1 Source")
|
|
TEST_VARIATION(12, L"Multi-User - 3 Sinks / 1 Source")
|
|
TEST_VARIATION(13, L"Multi-User - 1 Sink / 3 Sources")
|
|
TEST_VARIATION(14, L"Multi-User - 3 Sinks / 3 Sources")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCGetConnectionInterface)
|
|
//--------------------------------------------------------------------
|
|
// @class Test IConnectionPoint::GetConnectionInterface
|
|
//
|
|
class TCGetConnectionInterface : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCGetConnectionInterface,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - enum over the CPC and verify method
|
|
int Variation_1();
|
|
// @cmember Boundary/NULL - pIID == NULL
|
|
int Variation_2();
|
|
// @cmember Multi-User - 2 Sinks / 3 Sources verify
|
|
int Variation_3();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCGetConnectionInterface)
|
|
#define THE_CLASS TCGetConnectionInterface
|
|
BEG_TEST_CASE(TCGetConnectionInterface, CTestNotify, L"Test IConnectionPoint::GetConnectionInterface")
|
|
TEST_VARIATION(1, L"General - enum over the CPC and verify method")
|
|
TEST_VARIATION(2, L"Boundary/NULL - pIID == NULL")
|
|
TEST_VARIATION(3, L"Multi-User - 2 Sinks / 3 Sources verify")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCGetConnectionPointContainer)
|
|
//--------------------------------------------------------------------
|
|
// @class Test IConnectionPoint::GetConnectionPointContainer
|
|
//
|
|
class TCGetConnectionPointContainer : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCGetConnectionPointContainer,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - verify reference count
|
|
int Variation_1();
|
|
// @cmember General - Enum over the CP and verify correct container
|
|
int Variation_2();
|
|
// @cmember General - call release and verify ref count
|
|
int Variation_3();
|
|
// @cmember Boundary/NULL - ppICPC NULL - E_POINTER
|
|
int Variation_4();
|
|
// @cmember Multi-User - 2 Sinks / 3 Sources and verify
|
|
int Variation_5();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCGetConnectionPointContainer)
|
|
#define THE_CLASS TCGetConnectionPointContainer
|
|
BEG_TEST_CASE(TCGetConnectionPointContainer, CTestNotify, L"Test IConnectionPoint::GetConnectionPointContainer")
|
|
TEST_VARIATION(1, L"General - verify reference count")
|
|
TEST_VARIATION(2, L"General - Enum over the CP and verify correct container")
|
|
TEST_VARIATION(3, L"General - call release and verify ref count")
|
|
TEST_VARIATION(4, L"Boundary/NULL - ppICPC NULL - E_POINTER")
|
|
TEST_VARIATION(5, L"Multi-User - 2 Sinks / 3 Sources and verify")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCEnumConnections)
|
|
//--------------------------------------------------------------------
|
|
// @class Test IConnectionPoint::EnumConnections
|
|
//
|
|
class TCEnumConnections : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCEnumConnections,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - verify reference count
|
|
int Variation_1();
|
|
// @cmember Boundary/NULL - ppEnum NULL - E_POINTER
|
|
int Variation_2();
|
|
// @cmember Boundary/NULL - Enum over No Connections
|
|
int Variation_3();
|
|
// @cmember Boundary/NULL - Enum over many connections
|
|
int Variation_4();
|
|
// @cmember Boundary/NULL - Enum on a non-supporting Enum CP
|
|
int Variation_5();
|
|
// @cmember Enum::Next[0, NULL, NULL] - no ele
|
|
int Variation_6();
|
|
// @cmember Enum::Next[0, valid, valid] - no ele
|
|
int Variation_7();
|
|
// @cmember Enum::Next[1, valid, NULL] - no ele
|
|
int Variation_8();
|
|
// @cmember Enum::Next[1, NULL, NULL] - no ele
|
|
int Variation_9();
|
|
// @cmember Enum::Next[3, valid, NULL] - no ele
|
|
int Variation_10();
|
|
// @cmember Enum::Next[ULONG_MAX, valid, valid] - no ele
|
|
int Variation_11();
|
|
// @cmember Enum::Next[valid, valid, valid] - no ele
|
|
int Variation_12();
|
|
// @cmember Enum::Next[0, valid, NULL] - no ele
|
|
int Variation_13();
|
|
// @cmember Enum::Next[1, NULL, valid] - no ele
|
|
int Variation_14();
|
|
// @cmember Enum::Next[1, valid, NULL] - 1 ele
|
|
int Variation_15();
|
|
// @cmember Enum::Next[N+1, valid, valid] - 5 ele
|
|
int Variation_16();
|
|
// @cmember Enum::Next[Next seperatly over list] - 5 ele
|
|
int Variation_17();
|
|
// @cmember Enum::Next[Next group of all 5] - 5 ele
|
|
int Variation_18();
|
|
// @cmember Enum::Next[sequence of both seperately and group] - N ele
|
|
int Variation_19();
|
|
// @cmember Enum::Skip[0] - no ele - E_INVALIDARG
|
|
int Variation_20();
|
|
// @cmember Enum::Skip[ULONG_MAX] - no ele - S_FALSE
|
|
int Variation_21();
|
|
// @cmember Enum::Skip[N] - no ele - S_FALSE
|
|
int Variation_22();
|
|
// @cmember Enum::Skip[N+1] - no ele - S_FALSE
|
|
int Variation_23();
|
|
// @cmember Enum::Skip[0] - N ele - E_INVALIDARG
|
|
int Variation_24();
|
|
// @cmember Enum::Skip[ULONG_MAX] - N ele - S_FALSE
|
|
int Variation_25();
|
|
// @cmember Enum::Skip[N] - N ele - S_OK
|
|
int Variation_26();
|
|
// @cmember Enum::Skip[N-1] - N ele - S_OK
|
|
int Variation_27();
|
|
// @cmember Enum::Skip[N+1] - N ele - S_FALSE
|
|
int Variation_28();
|
|
// @cmember Enum::Clone[NULL] - E_POINTER
|
|
int Variation_29();
|
|
// @cmember Enum::Clone[valid] - no ele - S_OK
|
|
int Variation_30();
|
|
// @cmember Enum::Clone[valid] - N ele - S_OK
|
|
int Variation_31();
|
|
// @cmember Sequence - Enum sequence testing
|
|
int Variation_32();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCEnumConnections)
|
|
#define THE_CLASS TCEnumConnections
|
|
BEG_TEST_CASE(TCEnumConnections, CTestNotify, L"Test IConnectionPoint::EnumConnections")
|
|
TEST_VARIATION(1, L"General - verify reference count")
|
|
TEST_VARIATION(2, L"Boundary/NULL - ppEnum NULL - E_POINTER")
|
|
TEST_VARIATION(3, L"Boundary/NULL - Enum over No Connections")
|
|
TEST_VARIATION(4, L"Boundary/NULL - Enum over many connections")
|
|
TEST_VARIATION(5, L"Boundary/NULL - Enum on a non-supporting Enum CP")
|
|
TEST_VARIATION(6, L"Enum::Next[0, NULL, NULL] - no ele")
|
|
TEST_VARIATION(7, L"Enum::Next[0, valid, valid] - no ele")
|
|
TEST_VARIATION(8, L"Enum::Next[1, valid, NULL] - no ele")
|
|
TEST_VARIATION(9, L"Enum::Next[1, NULL, NULL] - no ele")
|
|
TEST_VARIATION(10, L"Enum::Next[3, valid, NULL] - no ele")
|
|
TEST_VARIATION(11, L"Enum::Next[ULONG_MAX, valid, valid] - no ele")
|
|
TEST_VARIATION(12, L"Enum::Next[valid, valid, valid] - no ele")
|
|
TEST_VARIATION(13, L"Enum::Next[0, valid, NULL] - no ele")
|
|
TEST_VARIATION(14, L"Enum::Next[1, NULL, valid] - no ele")
|
|
TEST_VARIATION(15, L"Enum::Next[1, valid, NULL] - 1 ele")
|
|
TEST_VARIATION(16, L"Enum::Next[N+1, valid, valid] - 5 ele")
|
|
TEST_VARIATION(17, L"Enum::Next[Next seperatly over list] - 5 ele")
|
|
TEST_VARIATION(18, L"Enum::Next[Next group of all 5] - 5 ele")
|
|
TEST_VARIATION(19, L"Enum::Next[sequence of both seperately and group] - N ele")
|
|
TEST_VARIATION(20, L"Enum::Skip[0] - no ele - E_INVALIDARG")
|
|
TEST_VARIATION(21, L"Enum::Skip[ULONG_MAX] - no ele - S_FALSE")
|
|
TEST_VARIATION(22, L"Enum::Skip[N] - no ele - S_FALSE")
|
|
TEST_VARIATION(23, L"Enum::Skip[N+1] - no ele - S_FALSE")
|
|
TEST_VARIATION(24, L"Enum::Skip[0] - N ele - E_INVALIDARG")
|
|
TEST_VARIATION(25, L"Enum::Skip[ULONG_MAX] - N ele - S_FALSE")
|
|
TEST_VARIATION(26, L"Enum::Skip[N] - N ele - S_OK")
|
|
TEST_VARIATION(27, L"Enum::Skip[N-1] - N ele - S_OK")
|
|
TEST_VARIATION(28, L"Enum::Skip[N+1] - N ele - S_FALSE")
|
|
TEST_VARIATION(29, L"Enum::Clone[NULL] - E_POINTER")
|
|
TEST_VARIATION(30, L"Enum::Clone[valid] - no ele - S_OK")
|
|
TEST_VARIATION(31, L"Enum::Clone[valid] - N ele - S_OK")
|
|
TEST_VARIATION(32, L"Sequence - Enum sequence testing")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCEnumConnectionPoints)
|
|
//--------------------------------------------------------------------
|
|
// @class Test IConnectionPointContainer::EnumConnectionPoints
|
|
//
|
|
class TCEnumConnectionPoints : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCEnumConnectionPoints,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - verify reference count
|
|
int Variation_1();
|
|
// @cmember General - verify QueryInterface for every connection point
|
|
int Variation_2();
|
|
// @cmember Boundary/NULL - ppEnum NULL E_POINTER
|
|
int Variation_3();
|
|
// @cmember EnumCP::Next[0,NULL,NULL]
|
|
int Variation_4();
|
|
// @cmember EnumCP::Next[0, valid, valid]
|
|
int Variation_5();
|
|
// @cmember EnumCP::Next[1, valid, NULL]
|
|
int Variation_6();
|
|
// @cmember EnumCP::Next[1, NULL, NULL]
|
|
int Variation_7();
|
|
// @cmember EnumCP::Next[ULONG_MAX, valid, valid]
|
|
int Variation_8();
|
|
// @cmember EnumCP::Next[valid, valid, valid]
|
|
int Variation_9();
|
|
// @cmember EnumCP::Next[0, valid, NULL]
|
|
int Variation_10();
|
|
// @cmember EnumCP::Next[1, NULL, valid]
|
|
int Variation_11();
|
|
// @cmember EnumCP::Next[N+1, valid, valid]
|
|
int Variation_12();
|
|
// @cmember EnumCP::Next[seperately]
|
|
int Variation_13();
|
|
// @cmember EnumCP::Next[group]
|
|
int Variation_14();
|
|
// @cmember EnumCP::Next[sequence]
|
|
int Variation_15();
|
|
// @cmember EnumCP::Skip[0]
|
|
int Variation_16();
|
|
// @cmember EnumCP::Skip[ULONG_MAX]
|
|
int Variation_17();
|
|
// @cmember EnumCP::Skip[N]
|
|
int Variation_18();
|
|
// @cmember EnumCP::Skip[N+1]
|
|
int Variation_19();
|
|
// @cmember EnumCP::Skip[N-1]
|
|
int Variation_20();
|
|
// @cmember EnumCP::Clone[NULL]
|
|
int Variation_21();
|
|
// @cmember EnumCP::Clone[valid]
|
|
int Variation_22();
|
|
// @cmember Sequence - EnumCP sequence testing
|
|
int Variation_23();
|
|
// @cmember General - verify correct IID returned
|
|
int Variation_24();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCEnumConnectionPoints)
|
|
#define THE_CLASS TCEnumConnectionPoints
|
|
BEG_TEST_CASE(TCEnumConnectionPoints, CTestNotify, L"Test IConnectionPointContainer::EnumConnectionPoints")
|
|
TEST_VARIATION(1, L"General - verify reference count")
|
|
TEST_VARIATION(2, L"General - verify QueryInterface for every connection point")
|
|
TEST_VARIATION(3, L"Boundary/NULL - ppEnum NULL E_POINTER")
|
|
TEST_VARIATION(4, L"EnumCP::Next[0,NULL,NULL]")
|
|
TEST_VARIATION(5, L"EnumCP::Next[0, valid, valid]")
|
|
TEST_VARIATION(6, L"EnumCP::Next[1, valid, NULL]")
|
|
TEST_VARIATION(7, L"EnumCP::Next[1, NULL, NULL]")
|
|
TEST_VARIATION(8, L"EnumCP::Next[ULONG_MAX, valid, valid]")
|
|
TEST_VARIATION(9, L"EnumCP::Next[valid, valid, valid]")
|
|
TEST_VARIATION(10, L"EnumCP::Next[0, valid, NULL]")
|
|
TEST_VARIATION(11, L"EnumCP::Next[1, NULL, valid]")
|
|
TEST_VARIATION(12, L"EnumCP::Next[N+1, valid, valid]")
|
|
TEST_VARIATION(13, L"EnumCP::Next[seperately]")
|
|
TEST_VARIATION(14, L"EnumCP::Next[group]")
|
|
TEST_VARIATION(15, L"EnumCP::Next[sequence]")
|
|
TEST_VARIATION(16, L"EnumCP::Skip[0]")
|
|
TEST_VARIATION(17, L"EnumCP::Skip[ULONG_MAX]")
|
|
TEST_VARIATION(18, L"EnumCP::Skip[N]")
|
|
TEST_VARIATION(19, L"EnumCP::Skip[N+1]")
|
|
TEST_VARIATION(20, L"EnumCP::Skip[N-1]")
|
|
TEST_VARIATION(21, L"EnumCP::Clone[NULL]")
|
|
TEST_VARIATION(22, L"EnumCP::Clone[valid]")
|
|
TEST_VARIATION(23, L"Sequence - EnumCP sequence testing")
|
|
TEST_VARIATION(24, L"General - verify correct IID returned")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCFindConnectionPoint)
|
|
//--------------------------------------------------------------------
|
|
// @class Test IConnectionPointInterface::FindConnectionPoint
|
|
//
|
|
class TCFindConnectionPoint : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCFindConnectionPoint,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember General - verify reference count
|
|
int Variation_1();
|
|
// @cmember Empty
|
|
int Variation_2();
|
|
// @cmember General - call repeatedly and verify reference count
|
|
int Variation_3();
|
|
// @cmember Boundary/NULL - riid NULL CONNECT_E_NOCONNECTION
|
|
int Variation_4();
|
|
// @cmember Boundary/NULL - ppICP E_POINTER
|
|
int Variation_5();
|
|
// @cmember Boundary/NULL - verify valid / invalid CP
|
|
int Variation_6();
|
|
// @cmember Multi-User - 2 Sinks / 1 Source verify IID returned
|
|
int Variation_7();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCFindConnectionPoint)
|
|
#define THE_CLASS TCFindConnectionPoint
|
|
BEG_TEST_CASE(TCFindConnectionPoint, CTestNotify, L"Test IConnectionPointInterface::FindConnectionPoint")
|
|
TEST_VARIATION(1, L"General - verify reference count")
|
|
TEST_VARIATION(2, L"Empty")
|
|
TEST_VARIATION(3, L"General - call repeatedly and verify reference count")
|
|
TEST_VARIATION(4, L"Boundary/NULL - riid NULL CONNECT_E_NOCONNECTION")
|
|
TEST_VARIATION(5, L"Boundary/NULL - ppICP E_POINTER")
|
|
TEST_VARIATION(6, L"Boundary/NULL - verify valid / invalid CP")
|
|
TEST_VARIATION(7, L"Multi-User - 2 Sinks / 1 Source verify IID returned")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCNotReEntrant)
|
|
//--------------------------------------------------------------------
|
|
// @class Test all interfaces that will return DB_E_NOTREENTRANT
|
|
//
|
|
class TCNotReEntrant : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCNotReEntrant,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
//IRowset - reentrantcy methods
|
|
static HRESULT RE_AddRefRows (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_GetData (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_GetNextRows (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_ReleaseRows (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_RestartPosition(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
|
|
//IRowsetChange - reentrantcy methods
|
|
static HRESULT RE_DeleteRows (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_InsertRow (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_SetData (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
|
|
//IRowsetUpdate - reentrantcy methods
|
|
static HRESULT RE_GetOriginalData(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_GetPendingRows (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_GetRowStatus (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_Undo (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
static HRESULT RE_Update (CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[]);
|
|
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember IRowset
|
|
int Variation_1();
|
|
// @cmember IRowsetChange
|
|
int Variation_2();
|
|
// @cmember IRowsetUpdate
|
|
int Variation_3();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCNotReEntrant)
|
|
#define THE_CLASS TCNotReEntrant
|
|
BEG_TEST_CASE(TCNotReEntrant, CTestNotify, L"Test all interfaces that will return DB_E_NOTREENTRANT")
|
|
TEST_VARIATION(1, L"IRowset")
|
|
TEST_VARIATION(2, L"IRowsetChange")
|
|
TEST_VARIATION(3, L"IRowsetUpdate")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCZombie)
|
|
//--------------------------------------------------------------------
|
|
// @class Test the zombie cases for ICPC/ICP
|
|
//
|
|
class TCZombie : public TCTransaction {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCZombie,TCTransaction);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
ULONG m_cPropSets;
|
|
DBPROPSET* m_rgPropSets;
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Zombie - ABORT with fRetaining == TRUE
|
|
int Variation_1();
|
|
// @cmember Zombie - ABORT with fRetaining == FALSE
|
|
int Variation_2();
|
|
// @cmember Zombie - COMMIT with fRetaining == TRUE
|
|
int Variation_3();
|
|
// @cmember Zombie - COMMIT with fRetaining == FALSE
|
|
int Variation_4();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCZombie)
|
|
#define THE_CLASS TCZombie
|
|
BEG_TEST_CASE(TCZombie, TCTransaction, L"Test the zombie cases for ICPC/ICP")
|
|
TEST_VARIATION(1, L"Zombie - ABORT with fRetaining == TRUE")
|
|
TEST_VARIATION(2, L"Zombie - ABORT with fRetaining == FALSE")
|
|
TEST_VARIATION(3, L"Zombie - COMMIT with fRetaining == TRUE")
|
|
TEST_VARIATION(4, L"Zombie - COMMIT with fRetaining == FALSE")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCProperties)
|
|
//--------------------------------------------------------------------
|
|
// @class Test all of the Notifcation properties
|
|
//
|
|
class TCProperties : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCProperties,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember Properties - DBPROP_IConnectionPointContainer
|
|
int Variation_1();
|
|
// @cmember Properties - DBPROP_NOTIFICATIONPHASES
|
|
int Variation_2();
|
|
// @cmember Properties - DBPROP_NOTIFIY [Reasons]
|
|
int Variation_3();
|
|
// @cmember Properties - DBPROP_REENTRANTEVENTS
|
|
int Variation_4();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCProperties)
|
|
#define THE_CLASS TCProperties
|
|
BEG_TEST_CASE(TCProperties, CTestNotify, L"Test all of the Notifcation properties")
|
|
TEST_VARIATION(1, L"Properties - DBPROP_IConnectionPointContainer")
|
|
TEST_VARIATION(2, L"Properties - DBPROP_NOTIFICATIONPHASES")
|
|
TEST_VARIATION(3, L"Properties - DBPROP_NOTIFIY [Reasons]")
|
|
TEST_VARIATION(4, L"Properties - DBPROP_REENTRANTEVENTS")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCNotifyCanceled)
|
|
//--------------------------------------------------------------------
|
|
// @class Test CANCELED notification
|
|
//
|
|
class TCNotifyCanceled : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCNotifyCanceled,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember CANCELED - IRowset
|
|
int Variation_1();
|
|
// @cmember CANCELED - IRowsetChange
|
|
int Variation_2();
|
|
// @cmember CANCELED - IRowsetUpdate
|
|
int Variation_3();
|
|
// @cmember CANCELED - IRowsetLocate
|
|
int Variation_4();
|
|
// @cmember CANCELED - IRowsetResynch
|
|
int Variation_5();
|
|
// @cmember CANCELED - IRowsetScroll
|
|
int Variation_6();
|
|
// }} TCW_TESTVARS_END
|
|
};
|
|
// {{ TCW_TESTCASE(TCNotifyCanceled)
|
|
#define THE_CLASS TCNotifyCanceled
|
|
BEG_TEST_CASE(TCNotifyCanceled, CTestNotify, L"Test CANCELED notifications")
|
|
TEST_VARIATION(1, L"CANCELED - IRowset")
|
|
TEST_VARIATION(2, L"CANCELED - IRowsetChange")
|
|
TEST_VARIATION(3, L"CANCELED - IRowsetUpdate")
|
|
TEST_VARIATION(4, L"CANCELED - IRowsetLocate")
|
|
TEST_VARIATION(5, L"CANCELED - IRowsetResynch")
|
|
TEST_VARIATION(6, L"CANCELED - IRowsetScroll")
|
|
END_TEST_CASE()
|
|
#undef THE_CLASS
|
|
// }} TCW_TESTCASE_END
|
|
// }} TCW_TEST_CASE_MAP_END
|
|
|
|
|
|
// {{ TCW_TEST_CASE_MAP(TCNotifyFailure)
|
|
//--------------------------------------------------------------------
|
|
// @class Test E_FAIL from a listener
|
|
//
|
|
class TCNotifyFailure : public CTestNotify {
|
|
public:
|
|
// @cmember Static array of variations
|
|
DECLARE_TEST_CASE_DATA();
|
|
|
|
public:
|
|
// {{ TCW_DECLARE_FUNCS
|
|
// @cmember Execution Routine
|
|
DECLARE_TEST_CASE_FUNCS(TCNotifyFailure,CTestNotify);
|
|
// }} TCW_DECLARE_FUNCS_END
|
|
|
|
// @cmember Initialization Routine
|
|
virtual BOOL Init();
|
|
// @cmember Termination Routine
|
|
virtual BOOL Terminate();
|
|
|
|
// {{ TCW_TESTVARS()
|
|
// @cmember E_FAIL - IRowset
|
|
int Variation_1();
|
|
// @cmember E_FAIL - IRowsetChange
|
|
int Variation_2();
|
|
// @cmember E_FAIL - IRowsetUpdate
|
|
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(TCNotifyFailure)
|
|
#define THE_CLASS TCNotifyFailure
|
|
BEG_TEST_CASE(TCNotifyFailure, CTestNotify, L"Test E_FAIL from a listener")
|
|
TEST_VARIATION(1, L"E_FAIL - IRowset")
|
|
TEST_VARIATION(2, L"E_FAIL - IRowsetChange")
|
|
TEST_VARIATION(3, L"E_FAIL - IRowsetUpdate")
|
|
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
|
|
|
|
|
|
// }} END_DECLARE_TEST_CASES()
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// TCStream_General
|
|
//
|
|
////////////////////////////////////////////////////////////////////////
|
|
#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, param1, param2) \
|
|
case iCase: \
|
|
pCTestCase = new theClass(NULL); \
|
|
((theClass*)pCTestCase)->SetTestCaseParams(param1, param2); \
|
|
pCTestCase->SetOwningMod(iCase-1, pCThisTestModule); \
|
|
return pCTestCase;
|
|
|
|
|
|
//TCRowset
|
|
COPY_TEST_CASE(TCRowset_Advise_IRowsetNotify, TCAdvise)
|
|
COPY_TEST_CASE(TCRowset_Unadvise_IRowsetNotify, TCUnadvise)
|
|
COPY_TEST_CASE(TCRowset_GetConnectionInterface_IRowsetNotify, TCGetConnectionInterface)
|
|
COPY_TEST_CASE(TCRowset_GetConnectionPointContainer_IRowsetNotify, TCGetConnectionPointContainer)
|
|
COPY_TEST_CASE(TCRowset_EnumConnections_IRowsetNotify, TCEnumConnections)
|
|
COPY_TEST_CASE(TCRowset_EnumConnectionPoints_IRowsetNotify, TCEnumConnectionPoints)
|
|
COPY_TEST_CASE(TCRowset_FindConnectionPoint_IRowsetNotify, TCFindConnectionPoint)
|
|
COPY_TEST_CASE(TCRowset_NotReEntrant_IRowsetNotify, TCNotReEntrant)
|
|
COPY_TEST_CASE(TCRowset_Zombie_IRowsetNotify, TCZombie)
|
|
COPY_TEST_CASE(TCRowset_Properties_IRowsetNotify, TCProperties)
|
|
COPY_TEST_CASE(TCRowset_NotifyCanceled_IRowsetNotify, TCNotifyCanceled)
|
|
COPY_TEST_CASE(TCRowset_NotifyFailure_IRowsetNotify, TCNotifyFailure)
|
|
|
|
COPY_TEST_CASE(TCRowset_Advise_IDBAsynchNotify, TCAdvise)
|
|
COPY_TEST_CASE(TCRowset_Unadvise_IDBAsynchNotify, TCUnadvise)
|
|
COPY_TEST_CASE(TCRowset_GetConnectionInterface_IDBAsynchNotify, TCGetConnectionInterface)
|
|
COPY_TEST_CASE(TCRowset_GetConnectionPointContainer_IDBAsynchNotify, TCGetConnectionPointContainer)
|
|
COPY_TEST_CASE(TCRowset_EnumConnections_IDBAsynchNotify, TCEnumConnections)
|
|
COPY_TEST_CASE(TCRowset_FindConnectionPoint_IDBAsynchNotify, TCFindConnectionPoint)
|
|
|
|
//TCDataSource
|
|
COPY_TEST_CASE(TCDataSource_Advise, TCAdvise)
|
|
COPY_TEST_CASE(TCDataSource_Unadvise, TCUnadvise)
|
|
COPY_TEST_CASE(TCDataSource_GetConnectionInterface, TCGetConnectionInterface)
|
|
COPY_TEST_CASE(TCDataSource_GetConnectionPointContainer,TCGetConnectionPointContainer)
|
|
COPY_TEST_CASE(TCDataSource_EnumConnections, TCEnumConnections)
|
|
COPY_TEST_CASE(TCDataSource_EnumConnectionPoints, TCEnumConnectionPoints)
|
|
COPY_TEST_CASE(TCDataSource_FindConnectionPoint, TCFindConnectionPoint)
|
|
|
|
//TCRow
|
|
COPY_TEST_CASE(TCRow_Advise, TCAdvise)
|
|
COPY_TEST_CASE(TCRow_Unadvise, TCUnadvise)
|
|
COPY_TEST_CASE(TCRow_GetConnectionInterface, TCGetConnectionInterface)
|
|
COPY_TEST_CASE(TCRow_GetConnectionPointContainer, TCGetConnectionPointContainer)
|
|
COPY_TEST_CASE(TCRow_EnumConnections, TCEnumConnections)
|
|
COPY_TEST_CASE(TCRow_EnumConnectionPoints, TCEnumConnectionPoints)
|
|
COPY_TEST_CASE(TCRow_FindConnectionPoint, TCFindConnectionPoint)
|
|
|
|
//TCStream
|
|
COPY_TEST_CASE(TCStream_Advise, TCAdvise)
|
|
COPY_TEST_CASE(TCStream_Unadvise, TCUnadvise)
|
|
COPY_TEST_CASE(TCStream_GetConnectionInterface, TCGetConnectionInterface)
|
|
COPY_TEST_CASE(TCStream_GetConnectionPointContainer, TCGetConnectionPointContainer)
|
|
COPY_TEST_CASE(TCStream_EnumConnections, TCEnumConnections)
|
|
COPY_TEST_CASE(TCStream_EnumConnectionPoints, TCEnumConnectionPoints)
|
|
COPY_TEST_CASE(TCStream_FindConnectionPoint, TCFindConnectionPoint)
|
|
|
|
|
|
//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(12, ThisModule, gwszModuleDescrip)
|
|
TEST_CASE(1, TCAdvise)
|
|
TEST_CASE(2, TCUnadvise)
|
|
TEST_CASE(3, TCGetConnectionInterface)
|
|
TEST_CASE(4, TCGetConnectionPointContainer)
|
|
TEST_CASE(5, TCEnumConnections)
|
|
TEST_CASE(6, TCEnumConnectionPoints)
|
|
TEST_CASE(7, TCFindConnectionPoint)
|
|
TEST_CASE(8, TCNotReEntrant)
|
|
TEST_CASE(9, TCZombie)
|
|
TEST_CASE(10, TCProperties)
|
|
TEST_CASE(11, TCNotifyCanceled)
|
|
TEST_CASE(12, TCNotifyFailure)
|
|
END_TEST_MODULE()
|
|
// }} TCW_TESTMODULE_END
|
|
#else
|
|
TEST_MODULE(39, ThisModule, gwszModuleDescrip)
|
|
//Rowset - IConnectionPoint: IRowsetNotify, IDBAsynchNotify
|
|
TEST_CASE_WITH_PARAM(1, TCRowset_Advise_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(2, TCRowset_Unadvise_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(3, TCRowset_GetConnectionInterface_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(4, TCRowset_GetConnectionPointContainer_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(5, TCRowset_EnumConnections_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(6, TCRowset_EnumConnectionPoints_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(7, TCRowset_FindConnectionPoint_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(8, TCRowset_NotReEntrant_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(9, TCRowset_Zombie_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(10, TCRowset_Properties_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(11, TCRowset_NotifyCanceled_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
TEST_CASE_WITH_PARAM(12, TCRowset_NotifyFailure_IRowsetNotify, ROWSET_INTERFACE, IID_IRowsetNotify)
|
|
|
|
TEST_CASE_WITH_PARAM(13, TCRowset_Advise_IDBAsynchNotify, ROWSET_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(14, TCRowset_Unadvise_IDBAsynchNotify, ROWSET_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(15, TCRowset_GetConnectionInterface_IDBAsynchNotify, ROWSET_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(16, TCRowset_GetConnectionPointContainer_IDBAsynchNotify, ROWSET_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(17, TCRowset_EnumConnections_IDBAsynchNotify, ROWSET_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(18, TCRowset_FindConnectionPoint_IDBAsynchNotify, ROWSET_INTERFACE, IID_IDBAsynchNotify)
|
|
|
|
//DataSource - IConnectionPoint
|
|
TEST_CASE_WITH_PARAM(19, TCDataSource_Advise, DATASOURCE_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(20, TCDataSource_Unadvise, DATASOURCE_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(21, TCDataSource_GetConnectionInterface, DATASOURCE_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(22, TCDataSource_GetConnectionPointContainer, DATASOURCE_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(23, TCDataSource_EnumConnections, DATASOURCE_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(24, TCDataSource_EnumConnectionPoints, DATASOURCE_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(25, TCDataSource_FindConnectionPoint, DATASOURCE_INTERFACE, IID_IDBAsynchNotify)
|
|
|
|
//Row - IConnectionPoint
|
|
TEST_CASE_WITH_PARAM(26, TCRow_Advise, ROW_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(27, TCRow_Unadvise, ROW_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(28, TCRow_GetConnectionInterface, ROW_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(29, TCRow_GetConnectionPointContainer, ROW_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(30, TCRow_EnumConnections, ROW_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(31, TCRow_EnumConnectionPoints, ROW_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(32, TCRow_FindConnectionPoint, ROW_INTERFACE, IID_IDBAsynchNotify)
|
|
|
|
//Stream - IConnectionPoint
|
|
TEST_CASE_WITH_PARAM(33, TCStream_Advise, STREAM_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(34, TCStream_Unadvise, STREAM_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(35, TCStream_GetConnectionInterface, STREAM_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(36, TCStream_GetConnectionPointContainer, STREAM_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(37, TCStream_EnumConnections, STREAM_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(38, TCStream_EnumConnectionPoints, STREAM_INTERFACE, IID_IDBAsynchNotify)
|
|
TEST_CASE_WITH_PARAM(39, TCStream_FindConnectionPoint, STREAM_INTERFACE, IID_IDBAsynchNotify)
|
|
END_TEST_MODULE()
|
|
#endif
|
|
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCAdvise)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCAdvise - Test IConnectionPoint::Advise(
|
|
//| Created: 02/26/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAdvise::Init()
|
|
{
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(m_dwTestCaseParam2));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - verify reference count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_1()
|
|
{
|
|
TBEGIN
|
|
|
|
//Verify connections / reference count
|
|
TESTC(VerifyRefCount() && VerifyNoConnection());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - [null, valid] - E_POINTER
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
DWORD dwCookie = 1; //set to non-zero, need to test 0 after call
|
|
|
|
//Obtain the ConnectionPoint
|
|
IConnectionPoint* pIConnectionPoint = pCSource(0)->GetCP();
|
|
TESTC(pIConnectionPoint != NULL);
|
|
|
|
//The following is not a successful connection, so on return Cookie should == 0,
|
|
TESTC_(pIConnectionPoint->Advise(NULL, &dwCookie),E_POINTER);
|
|
TESTC(dwCookie==0);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - [valid, null] - E_POINTER
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_3()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise...
|
|
TESTC_(pCSource(0)->GetCP()->Advise(pCListener(0), NULL),E_POINTER);
|
|
|
|
CLEANUP:
|
|
//RefCounts should not have changed...
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - [invalid sink, valid] - CANNOTCONNECT
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_4()
|
|
{
|
|
TBEGIN
|
|
DWORD dwCookie = 1; //set to non-zero, need to test 0 after call
|
|
|
|
TESTC_(pCSource(0)->GetCP()->Advise(pCSource(0)->GetCP(), &dwCookie),CONNECT_E_CANNOTCONNECT);
|
|
|
|
//cookie should be 0
|
|
TESTC(dwCookie == 0);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - Max connections+1 | 20 connections
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_5()
|
|
{
|
|
TBEGIN
|
|
HRESULT hr = S_OK;
|
|
const ULONG cTimesConnected = 20;
|
|
ULONG iConn = 0;
|
|
|
|
//Allocate enough cookies so every connection point can have multiple connections each...
|
|
//The layout of the bufffer is a "2-Dimensional array".
|
|
// Connection Point Index (First index), and Connection within that Point (Second Index)
|
|
// So rgCookies[0][2] = First Connection Point, and thrid connection within that point.
|
|
// rgCookies[0][2] = rgCookies + (iCP*cTimesConnected) + iConn
|
|
|
|
//NOTE: We do this layout, so that we know which cookies go with which connection point.
|
|
//So all cookies in the rgCookies[0] should be unique (with themselves) and so on...
|
|
|
|
DWORD* rgCookies = NULL;
|
|
SAFE_ALLOC(rgCookies, DWORD, cTimesConnected * pCSource(0)->GetCountCP());
|
|
memset(rgCookies, 0, (cTimesConnected * pCSource(0)->GetCountCP())*sizeof(DWORD));
|
|
|
|
//Note: We do this for loops in reverse order so we end up with interleaved advise's
|
|
//ie: IRowsetNotify, IDBAsynchNotify, Other, IRowsetNotify, IDBAsynchNotify, Other, repeat...
|
|
for(iConn=0; iConn<cTimesConnected; iConn++)
|
|
{
|
|
//Advise all connections points
|
|
//This way we will have testing of advising the same listener for different notifications
|
|
//A very common user senario, since they is no need to have seperate objects for each
|
|
//notification interface, since they are different methods. You can easily have one
|
|
//listner than listens to both rowset data notifications, as well as rowset asynch population
|
|
//notifications...
|
|
for(ULONG iCP=0; iCP<pCSource(0)->GetCountCP(); iCP++)
|
|
{
|
|
DWORD* pdwCookie = &(rgCookies + (iCP*cTimesConnected))[iConn];
|
|
*pdwCookie = INVALID(DWORD); //Should be 0 on error...
|
|
|
|
//Advise this connection
|
|
TEST2C_(hr = pCSource(0)->GetCP(iCP)->Advise(pCListener(0), pdwCookie), S_OK, CONNECT_E_ADVISELIMIT);
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
//Make sure this is a unique cookie
|
|
//NOTE: We are doing "All" connection points in this loop. And a cookie only needs
|
|
//to be unique for that connection point. So make sure the cookie is unique for just
|
|
//that row...
|
|
for(ULONG iCookie=0; iCookie<iConn; iCookie++)
|
|
{
|
|
if(*pdwCookie == (rgCookies + (iCP*cTimesConnected))[iCookie])
|
|
TERROR("Not a unique cookie " << *pdwCookie);
|
|
}
|
|
|
|
//Verify
|
|
TESTC(*pdwCookie != 0);
|
|
}
|
|
else
|
|
{
|
|
//Verify
|
|
TESTC(*pdwCookie == 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
//Verify all connections
|
|
// TESTC(VerifyConnection(pCListener(0), pCSource(0), cCookies));
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections (in reverse order)
|
|
for(iConn=0; iConn<cTimesConnected; iConn++)
|
|
{
|
|
for(ULONG iCP=0; iCP<pCSource(0)->GetCountCP(); iCP++)
|
|
{
|
|
DWORD* pdwCookie = &(rgCookies + (iCP*cTimesConnected))[iConn];
|
|
if(*pdwCookie)
|
|
CHECK(pCSource(0)->GetCP(iCP)->Unadvise(*pdwCookie),S_OK);
|
|
}
|
|
}
|
|
//Verify Ref Count
|
|
VerifyRefCount();
|
|
SAFE_FREE(rgCookies);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Usage Context - valid call, (IID_IRowsetNotify with a notify sink
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_6()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connection / verify
|
|
TESTC(AdviseNum(1,1));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Usage Context - 3 valid calls, (IID_IRowsetNotify with a notify sink
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_7()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connection / verify
|
|
TESTC(Advise(pCListener(0), pCSource(0)));
|
|
TESTC(Advise(pCListener(1), pCSource(1)));
|
|
TESTC(Advise(pCListener(2), pCSource(2)));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Usage Context - invalid call, (IID_ISomeOther with a notify sink
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_8()
|
|
{
|
|
TBEGIN
|
|
DWORD dwCookie = 123;
|
|
CListener* pListener = new CListener(IID_IRowset);
|
|
SAFE_ADDREF(pListener);
|
|
|
|
//Try to advise a Listener to a CP that doesn't support that IID
|
|
//IE: An IRowsetNotify listener to a IDBAsynchStatus Connection Point...
|
|
TESTC_(pCSource(0)->GetCP(0)->Advise(pListener, &dwCookie), CONNECT_E_CANNOTCONNECT);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pListener);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Usage Context - valid / invalvid / valid calls
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_9()
|
|
{
|
|
TBEGIN
|
|
DWORD dwCookie = 0;
|
|
CListener* pListener = new CListener(IID_IConnectionPoint);
|
|
SAFE_ADDREF(pListener);
|
|
|
|
//Valid Advise call
|
|
TESTC(Advise(pCListener(0), pCSource(0)));
|
|
|
|
//Try to advise an IID_IRowsetNotify CP to a non-notify CP
|
|
TESTC_(pCSource(0)->GetCP(0)->Advise(pListener, &dwCookie),CONNECT_E_CANNOTCONNECT);
|
|
|
|
//Valid Advise call
|
|
TESTC(Advise(pCListener(2), pCSource(0)));
|
|
|
|
//Now, unadvise
|
|
TESTC(Unadvise(pCListener(0), pCSource(0)));
|
|
TESTC(Unadvise(pCListener(1), pCSource(0)));
|
|
TESTC(Unadvise(pCListener(2), pCSource(0)));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
SAFE_RELEASE(pListener);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaded - 2 Sinks / 1 Sources (Sep Threads
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_10()
|
|
{
|
|
//not fully implemented: the problem here is that the second thread executes
|
|
//after pCSource(0)->CauseNotification() (when we call END_THREADS) and doesn't receive any notifications
|
|
//need to find way to cause main thread wait until two threads advises - use events?
|
|
TOUTPUT("Variation is not fully implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
INIT_THREADS(TWO_THREADS);
|
|
IID iid = m_dwTestCaseParam2;
|
|
|
|
//Setup Thread Arguments
|
|
THREADARG T1Arg = { pCSource(0)->pICPC(), &iid};
|
|
|
|
//Create Threads
|
|
CREATE_THREAD(THREAD_ONE, Thread_AdviseListener,&T1Arg);
|
|
CREATE_THREAD(THREAD_TWO, Thread_AdviseListener,&T1Arg);
|
|
|
|
// START_THREADS();
|
|
|
|
Sleep(100); //Let the other threads actually get hookup and Listening
|
|
//Now cause the ROW_ACTIVE notifciation to occur
|
|
pCSource(0)->CauseNotification();
|
|
|
|
// END_THREADS();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaded - 2 Sinks / 3 Sources (Sep Threads
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_11()
|
|
{
|
|
//see note in V10
|
|
TOUTPUT("Variation is not fully implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
|
|
INIT_THREADS(SIX_THREADS);
|
|
IID iid = m_dwTestCaseParam2;
|
|
|
|
//Setup Thread Arguments
|
|
THREADARG T1Arg = { pCSource(0)->pICPC(), &iid };
|
|
THREADARG T2Arg = { pCSource(1)->pICPC(), &iid };
|
|
THREADARG T3Arg = { pCSource(2)->pICPC(), &iid };
|
|
|
|
//Create Threads
|
|
//2 Lisenters for Source 1
|
|
CREATE_THREAD(THREAD_ONE, Thread_AdviseListener,&T1Arg);
|
|
CREATE_THREAD(THREAD_TWO, Thread_AdviseListener,&T1Arg);
|
|
|
|
//2 Lisenters for Source 2
|
|
CREATE_THREAD(THREAD_THREE, Thread_AdviseListener,&T2Arg);
|
|
CREATE_THREAD(THREAD_FOUR, Thread_AdviseListener,&T2Arg);
|
|
|
|
//2 Lisenters for Source 3
|
|
CREATE_THREAD(THREAD_FIVE, Thread_AdviseListener,&T3Arg);
|
|
CREATE_THREAD(THREAD_SIX, Thread_AdviseListener,&T3Arg);
|
|
|
|
// START_THREADS();
|
|
|
|
Sleep(100); //Let the other threads actually get hookup and Listening
|
|
|
|
//Now cause the ROW_ACTIVE notifciation to occur
|
|
pCSource(0)->CauseNotification();
|
|
pCSource(1)->CauseNotification();
|
|
pCSource(2)->CauseNotification();
|
|
|
|
// END_THREADS();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaded - 2 Sinks / 1 Source (Sep DB Sessions
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_12()
|
|
{
|
|
//see note in V10
|
|
TOUTPUT("Variation is not fully implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
IID iid = m_dwTestCaseParam2;
|
|
|
|
INIT_THREADS(TWO_THREADS);
|
|
|
|
//Setup Thread Arguments
|
|
THREADARG T1Arg = { pCSource(0)->pICPC(), &iid };
|
|
|
|
//Create Threads
|
|
CREATE_THREAD(THREAD_ONE, Thread_AdviseListener,&T1Arg);
|
|
CREATE_THREAD(THREAD_TWO, Thread_AdviseListener,&T1Arg);
|
|
|
|
// START_THREADS();
|
|
|
|
Sleep(100); //Let the other threads actually get hookup and Listening
|
|
|
|
//Now cause the ROW_ACTIVE notifciation to occur
|
|
pCSource(0)->CauseNotification();
|
|
|
|
// END_THREADS();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaded - 2 Sinks / 3 Source (Sep DB Sessions
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_13()
|
|
{
|
|
//see note in V10
|
|
TOUTPUT("Variation is not fully implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
IID iid = m_dwTestCaseParam2;
|
|
|
|
INIT_THREADS(SIX_THREADS);
|
|
|
|
//Setup Thread Arguments
|
|
THREADARG T1Arg = { pCSource(0)->pICPC(), &iid };
|
|
THREADARG T2Arg = { pCSource(1)->pICPC(), &iid };
|
|
THREADARG T3Arg = { pCSource(2)->pICPC(), &iid };
|
|
|
|
//Create Threads
|
|
//2 Lisenters for Source 1
|
|
CREATE_THREAD(THREAD_ONE, Thread_AdviseListener,&T1Arg);
|
|
CREATE_THREAD(THREAD_TWO, Thread_AdviseListener,&T1Arg);
|
|
|
|
//2 Lisenters for Source 2
|
|
CREATE_THREAD(THREAD_THREE, Thread_AdviseListener,&T2Arg);
|
|
CREATE_THREAD(THREAD_FOUR, Thread_AdviseListener,&T2Arg);
|
|
|
|
//2 Lisenters for Source 3
|
|
CREATE_THREAD(THREAD_FIVE, Thread_AdviseListener,&T3Arg);
|
|
CREATE_THREAD(THREAD_SIX, Thread_AdviseListener,&T3Arg);
|
|
|
|
// START_THREADS();
|
|
|
|
Sleep(100); //Let the other threads actually get hookup and Listening
|
|
|
|
//Now cause the ROW_ACTIVE notifciation to occur
|
|
pCSource(0)->CauseNotification();
|
|
pCSource(1)->CauseNotification();
|
|
pCSource(2)->CauseNotification();
|
|
|
|
// END_THREADS();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 1 Sink / 1 Source
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_14()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connection / verify
|
|
TESTC(Advise(pCListener(0), pCSource(0)));
|
|
TESTC(Advise(pCListener(0), pCSource(0)));
|
|
TESTC(Advise(pCListener(0), pCSource(0)));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 2 Sinks / 1 Source
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_15()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connection / verify
|
|
TESTC(AdviseNum(2,1));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 1 Sink / 3 Sources
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_16()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connection / verify
|
|
TESTC(AdviseNum(1,3));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 2 Sinks / 3 Sources
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_17()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise sink 0 connection / verify
|
|
TESTC(AdviseNum(2,3));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//--------------------------------------------------------------------
|
|
// @mfunc RefCount - Release of Rowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCAdvise::Variation_18()
|
|
{
|
|
TBEGIN
|
|
|
|
//Need to verify that upon release of the rowset
|
|
//The Listeners are released, wither or not they were unadvised.
|
|
//If the rowset doesn't Unadvise/Release any remaining Listeners,
|
|
//They will be leaks for every listener and what objects the listeners use...
|
|
|
|
//We could just use our existing Array or Sources and Listeners, but if the
|
|
//Provider has a Reference count problem, then it will afect all following variations
|
|
//So just create a new Source and new Listener...
|
|
CListener* pCListener = NULL;
|
|
CSource* pCSource = NULL;
|
|
ULONG dwCookie = 0;
|
|
|
|
//Create a new Source
|
|
switch(m_dwTestCaseParam1)
|
|
{
|
|
case ROWSET_INTERFACE:
|
|
pCSource = new CRowsetSource(m_dwTestCaseParam2);
|
|
break;
|
|
|
|
case DATASOURCE_INTERFACE:
|
|
pCSource = new CAsynchDSOSource;
|
|
break;
|
|
|
|
case ROW_INTERFACE:
|
|
pCSource = new CAsynchRowSource;
|
|
break;
|
|
|
|
case STREAM_INTERFACE:
|
|
pCSource = new CAsynchStreamSource;
|
|
break;
|
|
|
|
default:
|
|
ASSERT(!L"Unhandled TestCase Type!");
|
|
break;
|
|
};
|
|
TESTC_PROVIDER(pCSource != NULL && pCSource->CreateSource());
|
|
|
|
//Create a new Listener
|
|
pCListener = new CListener(pCSource->GetIID());
|
|
TESTC(pCListener!=NULL);
|
|
pCListener->AddRef();
|
|
|
|
|
|
//Now advise the Listener
|
|
TESTC_(pCListener->Advise(&dwCookie, pCSource->pICPC(), pCSource->GetIID()),S_OK);
|
|
TESTC(dwCookie != 0);
|
|
|
|
//Now Release the Source
|
|
SAFE_DELETE(pCSource);
|
|
|
|
//Should have received ROWSET_RELEASE notification since the Source went away...
|
|
if (m_dwTestCaseParam2==IID_IRowsetNotify)
|
|
TESTC(pCListener->GetTimesNotified(DBREASON_ROWSET_RELEASE) > 0);
|
|
|
|
//Should only have 1 reference (our reference) left on the Listener
|
|
COMPC(GetRefCount(pCListener), 1);
|
|
|
|
CLEANUP:
|
|
SAFE_DELETE(pCSource);
|
|
SAFE_RELEASE(pCListener);
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCAdvise::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
}
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCUnadvise)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCUnadvise - Test IConnectionPoint::Unadvise(
|
|
//| Created: 02/29/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCUnadvise::Init()
|
|
{
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(m_dwTestCaseParam2));
|
|
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - verify reference count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_1()
|
|
{
|
|
//Verify No Connections
|
|
TESTC(VerifyRefCount() && VerifyNoConnection());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - [null] - NOCONNECTION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_2()
|
|
{
|
|
TESTC_(pCSource(0)->GetCP()->Unadvise(NULL),CONNECT_E_NOCONNECTION);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - Unadvise before any Advises
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_3()
|
|
{
|
|
TESTC_(pCSource(0)->GetCP()->Unadvise(ULONG_MAX),CONNECT_E_NOCONNECTION);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Advise/Unadivse 12 variations
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_4()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise 5 Connections [0..4]
|
|
DWORD rgCookie[5];
|
|
|
|
TESTC(Advise(pCListener(0), pCSource(0), &rgCookie[0]));
|
|
TESTC(Advise(pCListener(1), pCSource(0), &rgCookie[1]));
|
|
TESTC(Advise(pCListener(2), pCSource(0), &rgCookie[2]));
|
|
TESTC(Advise(pCListener(3), pCSource(0), &rgCookie[3]));
|
|
TESTC(Advise(pCListener(4), pCSource(0), &rgCookie[4]));
|
|
|
|
//Unadvise(cookie[4]+1) - CONNECT_E_NOCONNECTION
|
|
TESTC_(pCSource(0)->GetCP()->Unadvise(rgCookie[4]+1),CONNECT_E_NOCONNECTION);
|
|
|
|
//Unadvise(cookie[4]) - S_OK
|
|
TESTC(Unadvise(pCListener(4), pCSource(0)));
|
|
|
|
//Unadvise(cookie[4]) again - CONNECT_E_NOCONNECTION
|
|
TESTC_(pCSource(0)->GetCP()->Unadvise(rgCookie[4]),CONNECT_E_NOCONNECTION);
|
|
|
|
//Advise(cookie[4]) - S_OK
|
|
TESTC(Advise(pCListener(4), pCSource(0), &rgCookie[4]));
|
|
|
|
//Unadvise(cookie[3]) - S_OK
|
|
TESTC(Unadvise(pCListener(3), pCSource(0)));
|
|
|
|
//Unadvise(cookie[4]) - S_OK
|
|
TESTC(Unadvise(pCListener(4), pCSource(0)));
|
|
|
|
//Unadvise(cookie[4..0]) cookie[0..2] - S_OK, cookie[3..4] - CONNECT_E_NOCONNECTION
|
|
TESTC_(pCSource(0)->GetCP()->Unadvise(rgCookie[4]),CONNECT_E_NOCONNECTION);
|
|
TESTC_(pCSource(0)->GetCP()->Unadvise(rgCookie[3]),CONNECT_E_NOCONNECTION);
|
|
|
|
TESTC(Unadvise(pCListener(2), pCSource(0)));
|
|
TESTC(Unadvise(pCListener(1), pCSource(0)));
|
|
TESTC(Unadvise(pCListener(0), pCSource(0)));
|
|
|
|
TESTC_(pCSource(0)->GetCP()->Unadvise(rgCookie[0]),CONNECT_E_NOCONNECTION);
|
|
|
|
//Verify No Connections
|
|
TESTC(VerifyNoConnection());
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Enabled
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_5()
|
|
{
|
|
//Verify No Connections
|
|
TESTC(VerifyRefCount() && VerifyNoConnection());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Transactions - Disabled
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_6()
|
|
{
|
|
//Verify No Connections
|
|
TESTC(VerifyRefCount() && VerifyNoConnection());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaed - 1 Sink / 3 Sources (Sep Threads
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_7()
|
|
{
|
|
//this variation should test Multi-Thread case, but is not implemented and is duplicate of V13
|
|
TOUTPUT("Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(Advise(pCListener(0), pCSource(0)));
|
|
TESTC(Advise(pCListener(0), pCSource(1)));
|
|
TESTC(Advise(pCListener(0), pCSource(2)));
|
|
|
|
//Unadvise connections / verify
|
|
TESTC(Unadvise(pCListener(0), pCSource(2)));
|
|
TESTC(Unadvise(pCListener(0), pCSource(0)));
|
|
TESTC(Unadvise(pCListener(0), pCSource(1)));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaed - 3 Sinks / 3 Sources (Sep Threads
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_8()
|
|
{
|
|
//this variation should test Multi-Thread case, but is not implemented and is duplicate of V14
|
|
TOUTPUT("Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(AdviseNum(3,3))
|
|
|
|
CLEANUP:
|
|
//Unadvise connections / verify
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaed - 1 Sink / 3 Sources (Sep DB Sessions
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_9()
|
|
{
|
|
//this variation should test Multi-Thread case, but is not implemented and is duplicate of V13
|
|
TOUTPUT("Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(AdviseNum(1,3));
|
|
|
|
CLEANUP:
|
|
//Unadvise connections / verify
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-Threaed - 3 Sinks / 3 Sources (Sep DB Sessions
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_10()
|
|
{
|
|
//this variation should test Multi-Thread case, but is not implemented and is duplicate of V14
|
|
TOUTPUT("Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(AdviseNum(3,3));
|
|
|
|
CLEANUP:
|
|
//Unadvise connections / verify
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 1 Sink / 1 Source
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_11()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(AdviseNum(1,1));
|
|
|
|
CLEANUP:
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 3 Sinks / 1 Source
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_12()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(AdviseNum(3,1));
|
|
|
|
CLEANUP:
|
|
//Unadvise connections / verify
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 1 Sink / 3 Sources
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_13()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(AdviseNum(1,3));
|
|
|
|
CLEANUP:
|
|
//Unadvise connections / verify
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 3 Sinks / 3 Sources
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCUnadvise::Variation_14()
|
|
{
|
|
TBEGIN
|
|
|
|
//Advise connections / verify
|
|
TESTC(AdviseNum(3,3));
|
|
|
|
CLEANUP:
|
|
//Unadvise connections / verify
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCUnadvise::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCGetConnectionInterface)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCGetConnectionInterface - Test IConnectionPoint::GetConnectionInterface
|
|
//| Created: 02/29/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetConnectionInterface::Init()
|
|
{
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(m_dwTestCaseParam2));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - enum over the CPC and verify method
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionInterface::Variation_1()
|
|
{
|
|
//Create an enum over the entire CPC, loop through every CP, and verify that
|
|
//pICP->GetConnectionInterface(IID) returns an IID that when used with
|
|
//FindConnectionPoint(IID, pICP2), returns a CP so that pICP2 == pICP.
|
|
//Sounds simple enough...
|
|
IConnectionPoint* pICP2 = NULL;
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP(), IConnectionPoint*);
|
|
memset(rgpICP, 0, pCSource(0)->GetCountCP() * sizeof(IConnectionPoint*));
|
|
IEnumConnectionPoints* pIEnumCP = pCSource(0)->pIEnumCP();
|
|
IID iid;
|
|
|
|
ULONG i,cFetched = 213;
|
|
|
|
//Enumerate over the ConnectionPoints
|
|
TESTC_(pIEnumCP->Reset(),S_OK);
|
|
|
|
//Loop over supported connection points
|
|
for(i=0; i<pCSource(0)->GetCountCP(); i++)
|
|
{
|
|
TESTC_(pIEnumCP->Next(1, &rgpICP[i], &cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[i]));
|
|
|
|
//try to find the IID in the container
|
|
TESTC_(rgpICP[i]->GetConnectionInterface(&iid),S_OK);
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(iid, &pICP2),S_OK);
|
|
|
|
//Verify pointer is the same as pICP
|
|
TESTC(VerifyEqualICPoint(rgpICP[i], pICP2));
|
|
SAFE_RELEASE(pICP2);
|
|
}
|
|
|
|
//Verify were at the end
|
|
TESTC_(pIEnumCP->Next(1, &pICP2, &cFetched),S_FALSE);
|
|
TESTC(cFetched == 0);
|
|
|
|
//Verify ConnectionnPoints returned
|
|
TESTC(VerifyConnectionPoints(pCSource(0)->GetCountCP(), rgpICP));
|
|
|
|
CLEANUP:
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
SAFE_RELEASE(pICP2);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - pIID == NULL
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionInterface::Variation_2()
|
|
{
|
|
//pass pIID==NULL - should return E_POINTER
|
|
TESTC_(pCSource(0)->GetCP()->GetConnectionInterface(NULL),E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 2 Sinks / 3 Sources verify
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionInterface::Variation_3()
|
|
{
|
|
IConnectionPoint* pICP = NULL;
|
|
IID iid;
|
|
ULONG i;
|
|
|
|
TESTC(AdviseNum(2,3));
|
|
|
|
//loop through sources
|
|
for(i=0; i<3; i++)
|
|
{
|
|
//Find IID_IRowsetNotify CP
|
|
TESTC_(pCSource(i)->pICPC()->FindConnectionPoint(pCSource(i)->GetIID(), &pICP),S_OK);
|
|
|
|
//Test returned pICP with our CP
|
|
TESTC(VerifyEqualICPoint(pICP, pCSource(i)->GetCP()));
|
|
|
|
//Verify same IID even when connections are established
|
|
TESTC_(pICP->GetConnectionInterface(&iid),S_OK);
|
|
|
|
//verify IID returned is indeed the interface of the connection point...
|
|
TESTC(iid == pCSource(i)->GetIID());
|
|
|
|
//Release
|
|
SAFE_RELEASE(pICP);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetConnectionInterface::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCGetConnectionPointContainer)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCGetConnectionPointContainer - Test IConnectionPoint::GetConnectionPointContainer
|
|
//| Created: 02/29/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetConnectionPointContainer::Init()
|
|
{
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(m_dwTestCaseParam2));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - verify reference count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionPointContainer::Variation_1()
|
|
{
|
|
TBEGIN
|
|
BOOL fInitialized = TRUE;
|
|
|
|
//Obtain the CPC
|
|
IConnectionPointContainer* pICPC = NULL;
|
|
TESTC_(pCSource(0)->GetCP()->GetConnectionPointContainer(&pICPC),S_OK);
|
|
|
|
//Make sure whatever type of object this container is an interface of,
|
|
//that it also supports those interfaces. IE: If off the rowset,
|
|
//then QI for all rowset interfaces...
|
|
fInitialized = (pCSource(0)->GetObjectType() == DATASOURCE_INTERFACE) ? FALSE : TRUE;
|
|
TCOMPARE_(DefaultObjectTesting(pICPC, pCSource(0)->GetObjectType(), fInitialized));
|
|
|
|
//Valid CPC interfaces
|
|
TCHECK(QI(pICPC,IID_IConnectionPointContainer),S_OK);
|
|
|
|
//Invlid CPC interfaces
|
|
TCHECK(QI(pICPC,IID_IConnectionPoint),E_NOINTERFACE);
|
|
TCHECK(QI(pICPC,IID_IEnumConnections),E_NOINTERFACE);
|
|
TCHECK(QI(pICPC,IID_IEnumConnectionPoints),E_NOINTERFACE);
|
|
TCHECK(QI(pICPC,IID_IRowsetNotify),E_NOINTERFACE);
|
|
TCHECK(QI(pICPC,IID_IDBAsynchNotify),E_NOINTERFACE);
|
|
|
|
CLEANUP:
|
|
//Release
|
|
SAFE_RELEASE(pICPC);
|
|
|
|
//Verify connections / reference count
|
|
VerifyRefCount();
|
|
VerifyNoConnection();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - Enum over the CP and verify correct container
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionPointContainer::Variation_2()
|
|
{
|
|
IConnectionPointContainer* pICPC = NULL;
|
|
IConnectionPointContainer* pICPC2 = NULL;
|
|
|
|
IEnumConnectionPoints* pIEnumConnectionPoints = NULL;
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG cFetched = 213;
|
|
HRESULT hr = S_OK;
|
|
|
|
//loop through sources
|
|
for(ULONG i=0; i<3; i++)
|
|
{
|
|
//Obtain the CPC
|
|
TESTC_(pCSource(i)->GetCP()->GetConnectionPointContainer(&pICPC),S_OK);
|
|
|
|
//TEST_ returned pICPC with our CPC
|
|
TESTC(VerifyEqualICPC(pICPC, pCSource(i)->pICPC()));
|
|
|
|
//get Enum over the CPC
|
|
TESTC_(pICPC->EnumConnectionPoints(&pIEnumConnectionPoints),S_OK);
|
|
TESTC_(pIEnumConnectionPoints->Reset(),S_OK);
|
|
|
|
cFetched = 123;
|
|
//For each CP in the container, verify the parent CPC
|
|
while(cFetched)
|
|
{
|
|
//Obtain the first Element
|
|
hr = pIEnumConnectionPoints->Next(1, &pICP, &cFetched);
|
|
if(cFetched == 0)
|
|
{
|
|
TESTC_(hr, S_FALSE);
|
|
continue;
|
|
}
|
|
|
|
//Verify results
|
|
TESTC_(hr, S_OK);
|
|
TESTC(cFetched==1 && pICP!=NULL);
|
|
|
|
//get the IID of the returned CP
|
|
//Get the parent CPC
|
|
TESTC_(pICP->GetConnectionPointContainer(&pICPC2),S_OK);
|
|
|
|
//Verify it matches over already obtained CPC
|
|
TESTC(VerifyEqualICPC(pICPC, pICPC2));
|
|
|
|
//Release
|
|
SAFE_RELEASE(pICPC2);
|
|
SAFE_RELEASE(pICP);
|
|
}
|
|
|
|
//Release
|
|
SAFE_RELEASE(pICPC);
|
|
SAFE_RELEASE(pIEnumConnectionPoints);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
SAFE_RELEASE(pIEnumConnectionPoints);
|
|
SAFE_RELEASE(pICPC);
|
|
SAFE_RELEASE(pICPC2);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - call release and verify ref count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionPointContainer::Variation_3()
|
|
{
|
|
TBEGIN
|
|
IConnectionPointContainer* rgpICPC[2] = {NULL,NULL};
|
|
int i=0;
|
|
//Call CPC twice
|
|
for(i=0; i<2; i++)
|
|
TESTC_(pCSource(0)->GetCP()->GetConnectionPointContainer(&rgpICPC[i]),S_OK);
|
|
|
|
CLEANUP:
|
|
//release / verify
|
|
for(i=0; i<2; i++)
|
|
SAFE_RELEASE(rgpICPC[i]);
|
|
|
|
|
|
//verify ref count
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - ppICPC NULL - E_POINTER
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionPointContainer::Variation_4()
|
|
{
|
|
TESTC_(pCSource(0)->GetCP()->GetConnectionPointContainer(NULL),E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 2 Sinks / 3 Sources and verify
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCGetConnectionPointContainer::Variation_5()
|
|
{
|
|
IConnectionPointContainer* pICPC = NULL;
|
|
IConnectionPointContainer* pICPC2 = NULL;
|
|
|
|
IEnumConnectionPoints* pIEnumConnectionPoints = NULL;
|
|
IConnectionPoint* pICP = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
ULONG cFetched = 123;
|
|
ULONG i;
|
|
|
|
TESTC(AdviseNum(2,3));
|
|
|
|
//loop through sources
|
|
for(i=0; i<3; i++)
|
|
{
|
|
//Obtain the CPC
|
|
TESTC_(pCSource(i)->GetCP()->GetConnectionPointContainer(&pICPC),S_OK);
|
|
|
|
//TEST_ returned pICPC with our CPC
|
|
TESTC(VerifyEqualICPC(pICPC, pCSource(i)->pICPC()));
|
|
|
|
//get Enum over the CPC
|
|
TESTC_(pICPC->EnumConnectionPoints(&pIEnumConnectionPoints),S_OK);
|
|
TESTC_(pIEnumConnectionPoints->Reset(),S_OK);
|
|
|
|
|
|
cFetched = 123;
|
|
//For each CP in the container, verify the parent CPC
|
|
while(cFetched)
|
|
{
|
|
//Obtain the first Element
|
|
hr = pIEnumConnectionPoints->Next(1, &pICP, &cFetched);
|
|
if(cFetched == 0)
|
|
{
|
|
TESTC_(hr, S_FALSE);
|
|
continue;
|
|
}
|
|
|
|
//Verify results
|
|
TESTC_(hr, S_OK);
|
|
TESTC(cFetched==1 && pICP!=NULL);
|
|
|
|
//get the IID of the returned CP
|
|
//Get the parent CPC
|
|
TESTC_(pICP->GetConnectionPointContainer(&pICPC2),S_OK);
|
|
|
|
//Verify it matches over already obtained CPC
|
|
TESTC(VerifyEqualICPC(pICPC, pICPC2));
|
|
|
|
//Release
|
|
SAFE_RELEASE(pICPC2);
|
|
SAFE_RELEASE(pICP);
|
|
}
|
|
|
|
SAFE_RELEASE(pICPC);
|
|
SAFE_RELEASE(pIEnumConnectionPoints);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
SAFE_RELEASE(pIEnumConnectionPoints);
|
|
SAFE_RELEASE(pICPC);
|
|
SAFE_RELEASE(pICPC2);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCGetConnectionPointContainer::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCEnumConnections)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCEnumConnections - Test IConnectionPoint::EnumConnections
|
|
//| Created: 02/29/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCEnumConnections::Init()
|
|
{
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(m_dwTestCaseParam2));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - verify reference count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_1()
|
|
{
|
|
//Obtain the EnumConnections
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//Make sure whatever type of object this container is an interface of,
|
|
//that it also supports those interfaces.
|
|
TCOMPARE_(DefaultObjectTesting(pIEnumConnections, UNKNOWN_INTERFACE));
|
|
|
|
//Valid CP interfaces
|
|
TCHECK(QI(pIEnumConnections,IID_IUnknown),S_OK);
|
|
|
|
//Invlid CP interfaces
|
|
TCHECK(QI(pIEnumConnections,IID_IConnectionPoint),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnections,IID_IEnumConnectionPoints),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnections,IID_IConnectionPointContainer),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnections,IID_IRowsetNotify),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnections,IID_IDBAsynchStatus),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnections,IID_IRowset),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnections,IID_IAccessor),E_NOINTERFACE);
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
//Verify connections / reference count
|
|
VerifyRefCount();
|
|
VerifyNoConnection();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - ppEnum NULL - E_POINTER
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_2()
|
|
{
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(NULL), E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - Enum over No Connections
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_3()
|
|
{
|
|
ULONG cFetched = 213;
|
|
CONNECTDATA rgConnectData[1] = { {INVALID_PUNK, INVALID_COOKIE} };
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP, currently no connections
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Get the next element
|
|
TESTC_(pIEnumConnections->Next(1,&rgConnectData[0],&cFetched),S_FALSE);
|
|
|
|
//On failure (S_FALSE), unused elements in rgpcn are not set to NULL
|
|
//and pcFetched holds the number of valid entries, even if 0 is returned
|
|
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - Enum over many connections
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_4()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[5] = {{NULL,0},{NULL,0},{NULL,0},{NULL,0},{NULL,0}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
const ULONG cCookies = 5;
|
|
DWORD rgCookies[cCookies];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookies));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Get all the elements
|
|
TESTC_(pIEnumConnections->Next(5, rgConnectData, &cFetched),S_OK);
|
|
TESTC(cFetched == 5 && rgConnectData[4].pUnk!=NULL && rgConnectData[4].dwCookie!=NULL);
|
|
|
|
//Need to verify the returned element is one of the actual connections
|
|
TESTC(VerifyConnectData(cFetched, rgConnectData, cCookies, rgCookies));
|
|
|
|
CLEANUP:
|
|
for(ULONG i=0;i<5;i++)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - Enum on a non-supporting Enum CP
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_5()
|
|
{
|
|
TBEGIN
|
|
ULONG i,cFetched = 123;
|
|
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
IConnectionPoint* pICP2 = NULL;
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP(), IConnectionPoint*);
|
|
memset(rgpICP, 0, pCSource(0)->GetCountCP() * sizeof(IConnectionPoint*));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//For each CP in the container, verify the parent CPC
|
|
for(i=0; i<pCSource(0)->GetCountCP(); i++)
|
|
{
|
|
//Obtain the first Element
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &rgpICP[i], &cFetched),S_OK);
|
|
TESTC(cFetched == 1);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[i]));
|
|
|
|
//get the IID of the returned CP
|
|
TESTC_(rgpICP[i]->EnumConnections(&pIEnumConnections),S_OK);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
}
|
|
|
|
//Verify were at the end
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &pICP2, &cFetched),S_FALSE);
|
|
TESTC(cFetched == 0);
|
|
|
|
//Verify ConnectionnPoints returned
|
|
TESTC(VerifyConnectionPoints(pCSource(0)->GetCountCP(), rgpICP));
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP2);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[0, NULL, NULL] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_6()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//(0, NULL, NULL)
|
|
//SPEC allows E_POINTER for rgpcn==NULL and E_INVALIDARG for cConnections==0
|
|
//So for (0,NULL,NULL) it is provider specific which they evaluate first
|
|
TEST2C_(pIEnumConnections->Next(0, NULL, NULL), E_POINTER, E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[0, valid, valid] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_7()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[1] = {{INVALID_PUNK, INVALID_COOKIE}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//Enum::Next(0, valid, valid)
|
|
//cConnections == 0 - E_INVALIDARG
|
|
TESTC_(pIEnumConnections->Next(0, rgConnectData, &cFetched), E_INVALIDARG);
|
|
|
|
//Spec says nothing about NULLing rgConnectData elements on E_INVALIDARG
|
|
TESTC(cFetched == 0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[1, valid, NULL] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_8()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1] = {{INVALID_PUNK, INVALID_COOKIE}};
|
|
|
|
//Obtain an Enum over the connections in the CP, currently no connections
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//No ele in list - S_FALSE (enumerator return fewer than asked)
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, NULL),S_FALSE);
|
|
|
|
//On failure (S_FALSE), unused elements in rgpcn are not set to NULL
|
|
//and pcFetched holds the number of valid entries, even if 0 is returned
|
|
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[1, NULL, NULL] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_9()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//rgpcd==NULL - E_POINTER
|
|
TESTC_(pIEnumConnections->Next(1,NULL,NULL),E_POINTER);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[3, valid, NULL] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_10()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[3] = {{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE}};
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//cConnections is not 1 when pcFetched == NULL - E_INVALIDARG
|
|
TESTC_(pIEnumConnections->Next(3, rgConnectData, NULL), E_INVALIDARG);
|
|
|
|
//Spec says nothing about NULLing reConnectData on error E_INVALIDARG
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[ULONG_MAX, valid, valid] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_11()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[2] = {{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//No ele in list - S_FALSE (enumerator return fewer than asked)
|
|
TESTC_(pIEnumConnections->Next(2, rgConnectData, &cFetched), S_FALSE);
|
|
|
|
//On failure (S_FALSE), unused elements in rgpcn are not set to NULL
|
|
//and pcFetched holds the number of valid entries, even if 0 is returned
|
|
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[valid, valid, valid] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_12()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[1] = {{INVALID_PUNK, INVALID_COOKIE}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//No ele in list - S_FALSE (enumerator return fewer than asked)
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
|
|
//On failure (S_FALSE), unused elements in rgpcn are not set to NULL
|
|
//and pcFetched holds the number of valid entries, even if 0 is returned
|
|
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[0, valid, NULL] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_13()
|
|
{
|
|
CONNECTDATA rgConnectData[1] = {{INVALID_PUNK, INVALID_COOKIE}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//cConnections == 0 - E_INVALIDARG
|
|
TESTC_(pIEnumConnections->Next(0, rgConnectData, NULL), E_INVALIDARG)
|
|
|
|
//Spec says nothing about NULLing rgConnectData on E_INVALIDARG
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[1, NULL, valid] - no ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_14()
|
|
{
|
|
ULONG cFetched= 213;
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
|
|
//rgpcn is NULL - E_POINTER
|
|
TESTC_(pIEnumConnections->Next(1, NULL, &cFetched), E_POINTER);
|
|
TESTC(cFetched == 0)
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[1, valid, NULL] - 1 ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_15()
|
|
{
|
|
CONNECTDATA rgConnectData[1] = {{NULL,0}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Advise 1 Connection
|
|
TESTC(Advise(pCListener(0), pCSource(0), &dwCookie));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Get the first connections
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, NULL),S_OK);
|
|
|
|
//verify 1 element returned
|
|
TESTC(VerifyEqualInterface(rgConnectData[0].pUnk, pCListener(0)));
|
|
TESTC(rgConnectData[0].dwCookie == dwCookie);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(rgConnectData[0].pUnk);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[N+1, valid, valid] - 5 ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_16()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[6]={{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE},{INVALID_PUNK, INVALID_COOKIE}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
const ULONG cCookies = 5;
|
|
DWORD rgCookies[cCookies];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookies));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Try to fetch more than is in the enum
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
TESTC_(pIEnumConnections->Next(6,rgConnectData,&cFetched),S_FALSE);
|
|
TESTC(cFetched == 5 && rgConnectData[4].pUnk!=INVALID_PUNK && rgConnectData[4].dwCookie!=INVALID_COOKIE);
|
|
|
|
//On failure (S_FALSE), unused elements in rgpcn are not set to NULL
|
|
//and pcFetched holds the number of valid entries, even if 0 is returned
|
|
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(rgConnectData[5].pUnk==INVALID_PUNK || rgConnectData[5].pUnk==NULL);
|
|
TESTC(rgConnectData[5].dwCookie==INVALID_COOKIE || rgConnectData[5].dwCookie==0);
|
|
|
|
//Need to verify rgConnectData array
|
|
TESTC(VerifyConnectData(cFetched, rgConnectData, cCookies, rgCookies));
|
|
|
|
CLEANUP:
|
|
for(ULONG i=0; i<6; i++)
|
|
if(rgConnectData[i].pUnk!=INVALID_PUNK)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
//Now Unadvise Connections
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[Next seperatly over list] - 5 ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_17()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[5]={{NULL,0},{NULL,0},{NULL,0},{NULL,0},{NULL,0}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
const ULONG cCookies = 5;
|
|
DWORD rgCookies[cCookies];
|
|
ULONG i=0;
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookies));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
for(i=0; i<5; i++)
|
|
{
|
|
//Get the next element
|
|
cFetched = 123;
|
|
TESTC_(pIEnumConnections->Next(1,&rgConnectData[i],&cFetched),S_OK);
|
|
TESTC(cFetched == 1 && rgConnectData[i].pUnk!=NULL && rgConnectData[i].dwCookie!=NULL);
|
|
|
|
//Need to verify rgConnectData array
|
|
TESTC(VerifyConnectData(cFetched, &rgConnectData[i], cCookies, rgCookies));
|
|
}
|
|
|
|
CLEANUP:
|
|
for(i=0; i<5; i++)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[Next group of all 5] - 5 ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_18()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[5]={{NULL,0},{NULL,0},{NULL,0},{NULL,0},{NULL,0}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
const ULONG cCookies = 5;
|
|
DWORD rgCookies[cCookies];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookies));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Try to fetch the enum
|
|
TESTC_(pIEnumConnections->Next(5, rgConnectData, &cFetched),S_OK);
|
|
TESTC(cFetched == 5 && rgConnectData[4].pUnk!=NULL && rgConnectData[4].dwCookie!=NULL);
|
|
|
|
//Need to verify rgConnectData array
|
|
TESTC(VerifyConnectData(cFetched, rgConnectData, cCookies, rgCookies));
|
|
|
|
CLEANUP:
|
|
for(ULONG i=0; i<5; i++)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
//Now Unadvise Connections
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Next[sequence of both seperately and group] - N ele
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_19()
|
|
{
|
|
ULONG cFetched= 213;
|
|
CONNECTDATA rgConnectData[5]={{NULL,0},{NULL,0},{NULL,0},{NULL,0},{NULL,0}};
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
|
|
const ULONG cCookies = 5;
|
|
DWORD rgCookies[cCookies];
|
|
ULONG i=0;
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookies));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Try to fetch more than is in the enum
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
TESTC_(pIEnumConnections->Next(4,rgConnectData,&cFetched),S_OK);
|
|
TESTC(cFetched == 4 && rgConnectData[3].pUnk!=NULL && rgConnectData[3].dwCookie!=NULL);
|
|
|
|
//Need to verify rgConnectData array
|
|
TESTC(VerifyConnectData(cFetched, rgConnectData, cCookies, rgCookies));
|
|
for(i=0; i<5; i++)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
|
|
//Reset the enum
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Move position away from head
|
|
cFetched=123;
|
|
TESTC_(pIEnumConnections->Next(1,&rgConnectData[0],&cFetched),S_OK);
|
|
TESTC(cFetched==1 && rgConnectData[0].pUnk!=NULL && rgConnectData[0].dwCookie!=NULL);
|
|
|
|
//Need to verify rgConnectData array
|
|
TESTC(VerifyConnectData(cFetched, &rgConnectData[0], cCookies, rgCookies));
|
|
SAFE_RELEASE(rgConnectData[0].pUnk);
|
|
|
|
//Try to fetch one more than is left in the enum
|
|
TESTC_(pIEnumConnections->Next(5,rgConnectData,&cFetched),S_FALSE);
|
|
TESTC(cFetched == 4 && rgConnectData[3].pUnk!=NULL && rgConnectData[3].dwCookie!=NULL);
|
|
|
|
//Need to verify rgConnectData array
|
|
TESTC(VerifyConnectData(cFetched, rgConnectData, cCookies, rgCookies));
|
|
|
|
CLEANUP:
|
|
for(i=0; i<5; i++)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
//Now Unadvise Connections
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[0] - no ele - E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_20()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(0) - E_INVALIDARG
|
|
TESTC_(pIEnumConnections->Skip(0), E_INVALIDARG);
|
|
|
|
//Verify position is unchanged
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[ULONG_MAX] - no ele - S_FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_21()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(ULONG_MAX) - S_FALSE
|
|
TESTC_(pIEnumConnections->Skip(ULONG_MAX), S_FALSE);
|
|
|
|
//Verify position is at the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
//Once position is moved away from head, Skip(ULONG_MAX) - S_FALSE
|
|
TESTC_(pIEnumConnections->Skip(ULONG_MAX), S_FALSE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[N] - no ele - S_FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_22()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(N) - S_OK
|
|
TESTC_(pIEnumConnections->Skip(5), S_FALSE);
|
|
|
|
//Verify position is at the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[N+1] - no ele - S_FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_23()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(N+1) - S_FALSE
|
|
TESTC_(pIEnumConnections->Skip(5+1), S_FALSE);
|
|
|
|
//Verify position is at the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[0] - N ele - E_INVALIDARG
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_24()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[5]={{NULL,0},{NULL,0},{NULL,0},{NULL,0},{NULL,0}};
|
|
ULONG i, cFetched= 213;
|
|
DWORD rgCookie[5];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookie));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(0) - E_INVALIDARG
|
|
TESTC_(pIEnumConnections->Skip(0), E_INVALIDARG);
|
|
|
|
//Verify position is unchanged
|
|
TESTC_(pIEnumConnections->Next(5, rgConnectData, &cFetched),S_OK);
|
|
TESTC(cFetched==5 && rgConnectData[4].pUnk!=NULL && rgConnectData[4].dwCookie!=0);
|
|
|
|
CLEANUP:
|
|
for(i=0; i<5; i++)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(25)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[ULONG_MAX] - N ele - S_FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_25()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
DWORD rgCookie[5];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookie));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(ULONG_MAX) - S_FALSE
|
|
TESTC_(pIEnumConnections->Skip(ULONG_MAX), S_FALSE);
|
|
|
|
//Verify position is at the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
//Oce position is away from head, Skip(ULONG_MAX) - S_FALSE
|
|
TESTC_(pIEnumConnections->Skip(ULONG_MAX), S_FALSE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(26)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[N] - N ele - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_26()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
DWORD rgCookie[5];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookie));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(N) - S_OK
|
|
TESTC_(pIEnumConnections->Skip(5), S_OK);
|
|
|
|
//Verify position is at the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(27)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[N-1] - N ele - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_27()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{NULL,0}};
|
|
ULONG cFetched= 213;
|
|
|
|
const ULONG cCookies = 5;
|
|
DWORD rgCookies[cCookies];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookies));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(N-1) - S_OK
|
|
TESTC_(pIEnumConnections->Skip(5-1), S_OK);
|
|
|
|
//Verify position is ONE from the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_OK);
|
|
TESTC(cFetched==1 && rgConnectData[0].pUnk!=NULL && rgConnectData[0].dwCookie!=0);
|
|
TESTC(VerifyConnectData(cFetched, rgConnectData, cCookies, rgCookies));
|
|
|
|
rgConnectData[0].dwCookie = 0;
|
|
SAFE_RELEASE(rgConnectData[0].pUnk);
|
|
|
|
//Verify position is at the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
TESTC(cFetched==0 && rgConnectData[0].pUnk==NULL && rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(rgConnectData[0].pUnk);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(28)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Skip[N+1] - N ele - S_FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_28()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
DWORD rgCookie[5];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookie));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Skip(N+1) - S_FALSE
|
|
TESTC_(pIEnumConnections->Skip(5+1), S_FALSE);
|
|
|
|
//Verify position is at the end
|
|
TESTC_(pIEnumConnections->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
//Even this is what the spec indicates, it doesn't make much sense, as remoting proxies
|
|
//and stubs need to null this out so no remoting occurs for these objects. So we will
|
|
//allow either untouched our nulled internal members...
|
|
TESTC(cFetched==0);
|
|
TESTC(rgConnectData[0].pUnk==INVALID_PUNK || rgConnectData[0].pUnk==NULL);
|
|
TESTC(rgConnectData[0].dwCookie==INVALID_COOKIE || rgConnectData[0].dwCookie==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(29)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Clone[NULL] - E_POINTER
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_29()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
DWORD rgCookie[5];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookie));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Clone(NULL) - E_POINTER
|
|
TESTC_(pIEnumConnections->Clone(NULL), E_POINTER);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(30)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Clone[valid] - no ele - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_30()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
IEnumConnections* pIEnumClone = NULL;
|
|
CONNECTDATA rgConnectData[1]={{INVALID_PUNK, INVALID_COOKIE}};
|
|
ULONG cFetched= 213;
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Clone(valid) - S_OK
|
|
TESTC_(pIEnumConnections->Clone(&pIEnumClone), S_OK);
|
|
TESTC(pIEnumClone != NULL);
|
|
|
|
//Verify Clone
|
|
TESTC_(pIEnumClone->Next(1, rgConnectData, &cFetched),S_FALSE);
|
|
TESTC(cFetched==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
SAFE_RELEASE(pIEnumClone);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(31)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Enum::Clone[valid] - N ele - S_OK
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_31()
|
|
{
|
|
IEnumConnections* pIEnumConnections = NULL;
|
|
IEnumConnections* pIEnumClone = NULL;
|
|
CONNECTDATA rgConnectData[5]={{NULL,0},{NULL,0},{NULL,0},{NULL,0},{NULL,0}};
|
|
ULONG cFetched= 213;
|
|
|
|
const ULONG cCookies = 5;
|
|
DWORD rgCookies[cCookies];
|
|
|
|
//Advise 5 Connections
|
|
TESTC(AdviseNum(5,1,rgCookies));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&pIEnumConnections),S_OK);
|
|
TESTC_(pIEnumConnections->Reset(),S_OK);
|
|
|
|
//Clone(valid) - S_OK
|
|
TESTC_(pIEnumConnections->Clone(&pIEnumClone), S_OK);
|
|
TESTC(pIEnumClone != NULL);
|
|
|
|
//Verify Clone
|
|
TESTC_(pIEnumClone->Next(5, rgConnectData, &cFetched),S_OK);
|
|
TESTC(cFetched==5 && rgConnectData[4].pUnk!=NULL && rgConnectData[4].dwCookie!=0);
|
|
TESTC(VerifyConnectData(cFetched, rgConnectData, cCookies, rgCookies));
|
|
|
|
CLEANUP:
|
|
for(ULONG i=0; i<5; i++)
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
SAFE_RELEASE(pIEnumConnections);
|
|
SAFE_RELEASE(pIEnumClone);
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(32)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - Enum sequence testing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnections::Variation_32()
|
|
{
|
|
// rgpIEnumConnections[0] - Enum
|
|
// rgpIEnumConnections[1] - Clone of Enum[0]
|
|
// rgpIEnumConnections[2] - Clone of Enum[1]
|
|
CONNECTDATA rgConnectData[3] = {{NULL,0},{NULL,0},{NULL,0}};
|
|
CONNECTDATA rgTmpData[4] = {{NULL,0},{NULL,0},{NULL,0},{NULL,0}};
|
|
IEnumConnections* rgpIEnumConnections[3] = {NULL, NULL, NULL};
|
|
|
|
ULONG i,cFetched = 123;
|
|
|
|
//Obtain the enums
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&rgpIEnumConnections[0]),S_OK);
|
|
TESTC_(rgpIEnumConnections[0]->Clone(&rgpIEnumConnections[1]),S_OK);
|
|
TESTC_(rgpIEnumConnections[1]->Clone(&rgpIEnumConnections[2]),S_OK);
|
|
|
|
//Reset the enums
|
|
for(i=0; i<3; i++)
|
|
TESTC_(rgpIEnumConnections[i]->Reset(),S_OK);
|
|
|
|
//Verify no connections in the enum
|
|
for(i=0; i<3; i++)
|
|
{
|
|
cFetched = 123;
|
|
TESTC_(rgpIEnumConnections[i]->Next(1,&rgTmpData[0],&cFetched),S_FALSE);
|
|
TESTC(cFetched==0 && rgTmpData[0].pUnk==NULL && rgTmpData[0].dwCookie==NULL);
|
|
TESTC_(rgpIEnumConnections[i]->Reset(),S_OK);
|
|
}
|
|
|
|
//Advise 3 connections
|
|
TESTC(Advise(pCListener(0), pCSource(0)));
|
|
TESTC(Advise(pCListener(1), pCSource(0)));
|
|
TESTC(Advise(pCListener(2), pCSource(0)));
|
|
|
|
//Enums could be static so have to recreate them once
|
|
//there are more elements in the array...
|
|
for(i=0; i<3; i++)
|
|
SAFE_RELEASE(rgpIEnumConnections[i]);
|
|
|
|
//Obtain the enums again
|
|
TESTC_(pCSource(0)->GetCP()->EnumConnections(&rgpIEnumConnections[0]),S_OK);
|
|
TESTC_(rgpIEnumConnections[0]->Clone(&rgpIEnumConnections[1]),S_OK);
|
|
TESTC_(rgpIEnumConnections[1]->Clone(&rgpIEnumConnections[2]),S_OK);
|
|
|
|
//Obtain the CP pointers
|
|
TESTC_(rgpIEnumConnections[0]->Next(3,rgConnectData,&cFetched),S_OK);
|
|
TESTC(cFetched==3 && rgConnectData[0].pUnk!=NULL && rgConnectData[0].dwCookie!=NULL);
|
|
TESTC_(rgpIEnumConnections[0]->Reset(),S_OK);
|
|
|
|
//Advance next position of 2 and 3
|
|
TESTC_(rgpIEnumConnections[1]->Skip(1),S_OK);
|
|
TESTC_(rgpIEnumConnections[2]->Skip(2),S_OK);
|
|
|
|
//Should return matching connecion points
|
|
for(i=0; i<3; i++)
|
|
{
|
|
cFetched = 123;
|
|
TESTC_(rgpIEnumConnections[i]->Next(1,&rgTmpData[i],&cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyEqualInterface(rgTmpData[i].pUnk, rgConnectData[i].pUnk));
|
|
TESTC(rgTmpData[i].dwCookie==rgConnectData[i].dwCookie);
|
|
SAFE_RELEASE(rgTmpData[i].pUnk);
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
for(i=0; i<3; i++)
|
|
{
|
|
SAFE_RELEASE(rgConnectData[i].pUnk);
|
|
SAFE_RELEASE(rgpIEnumConnections[i]);
|
|
}
|
|
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCEnumConnections::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCEnumConnectionPoints)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCEnumConnectionPoints - Test IConnectionPointContainer::EnumConnectionPoints
|
|
//| Created: 02/29/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCEnumConnectionPoints::Init()
|
|
{
|
|
return CTestNotify::Init();
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - verify reference count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_1()
|
|
{
|
|
//Obtain the Enumerator over the CPs
|
|
IEnumConnectionPoints* pIEnumConnectionPoints = pCSource(0)->pIEnumCP();
|
|
TESTC(pIEnumConnectionPoints != NULL);
|
|
|
|
//Make sure whatever type of object this container is an interface of,
|
|
//that it also supports those interfaces.
|
|
TCOMPARE_(DefaultObjectTesting(pIEnumConnectionPoints, UNKNOWN_INTERFACE));
|
|
|
|
//Valid CP interfaces
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IEnumConnectionPoints),S_OK);
|
|
|
|
//Invlid CP interfaces
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IConnectionPoint),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IEnumConnections),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IConnectionPointContainer),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IRowsetNotify),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IDBAsynchNotify),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IRowset),E_NOINTERFACE);
|
|
TCHECK(QI(pIEnumConnectionPoints,IID_IAccessor),E_NOINTERFACE);
|
|
|
|
CLEANUP:
|
|
VerifyRefCount();
|
|
VerifyNoConnection();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - verify QueryInterface for every connection point
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_2()
|
|
{
|
|
TBEGIN
|
|
ULONG i,cFetched = 123;
|
|
IID iid;
|
|
|
|
IConnectionPoint* pICP2 = NULL;
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP(), IConnectionPoint*);
|
|
memset(rgpICP, 0, pCSource(0)->GetCountCP() * sizeof(IConnectionPoint*));
|
|
|
|
//Obtain an Enum over the connections in the CP
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//For each CP in the container, verify the parent CPC
|
|
for(i=0; i<pCSource(0)->GetCountCP(); i++)
|
|
{
|
|
//Obtain the first Element
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &rgpICP[i], &cFetched),S_OK);
|
|
TESTC(cFetched == 1);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[i]));
|
|
|
|
//get the IID of the returned CP
|
|
//Make sure the connection point is only exposing the interfaces that it should be
|
|
|
|
//Make sure whatever type of object this container is an interface of,
|
|
//that it also supports those interfaces.
|
|
TCOMPARE_(DefaultObjectTesting(rgpICP[i], UNKNOWN_INTERFACE));
|
|
|
|
//Valid CP interfaces
|
|
TCHECK(QI(rgpICP[i],IID_IConnectionPoint),S_OK);
|
|
|
|
//Invlid CP interfaces
|
|
TCHECK(QI(rgpICP[i],IID_IEnumConnectionPoints),E_NOINTERFACE);
|
|
TCHECK(QI(rgpICP[i],IID_IEnumConnections),E_NOINTERFACE);
|
|
TCHECK(QI(rgpICP[i],IID_IConnectionPointContainer),E_NOINTERFACE);
|
|
TCHECK(QI(rgpICP[i],IID_IRowsetNotify),E_NOINTERFACE);
|
|
TCHECK(QI(rgpICP[i],IID_IDBAsynchNotify),E_NOINTERFACE);
|
|
TCHECK(QI(rgpICP[i],IID_IRowset),E_NOINTERFACE);
|
|
TCHECK(QI(rgpICP[i],IID_IAccessor),E_NOINTERFACE);
|
|
|
|
TESTC_(rgpICP[i]->GetConnectionInterface(&iid),S_OK);
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(iid, &pICP2),S_OK);
|
|
|
|
//Verify it matches over already obtained pPC
|
|
TESTC(VerifyEqualICPoint(rgpICP[i], pICP2));
|
|
SAFE_RELEASE(pICP2);
|
|
}
|
|
|
|
//Verify were at the end
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &pICP2, &cFetched),S_FALSE);
|
|
TESTC(cFetched == 0);
|
|
|
|
//Verify ConnectionnPoints returned
|
|
TESTC(VerifyConnectionPoints(pCSource(0)->GetCountCP(), rgpICP));
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP2);
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - ppEnum NULL E_POINTER
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_3()
|
|
{
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pICPC()->EnumConnectionPoints(NULL),E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[0,NULL,NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_4()
|
|
{
|
|
//Enum::Next[0,NULL,NULL]
|
|
//cConnections==0 - E_INVALIDARG, rgpcn==NULL - E_POINTER
|
|
//So depending upon provider the order of validation can allow both
|
|
TEST2C_(pCSource(0)->pIEnumCP()->Next(0,NULL,NULL), E_INVALIDARG, E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[0, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_5()
|
|
{
|
|
TBEGIN
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG cFetched = 123;
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//Set position to tail
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &pICP, NULL), S_OK);
|
|
TESTC(VerifyConnectionPoints(1, &pICP));
|
|
SAFE_RELEASE(pICP);
|
|
|
|
//obtain 0 elements, cConnections == 0 - E_INVALIDARG
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(0, &pICP, &cFetched), E_INVALIDARG);
|
|
TESTC(cFetched == 0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[1, valid, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_6()
|
|
{
|
|
TBEGIN
|
|
IConnectionPoint* rgpICP[2] = {NULL,NULL};
|
|
ULONG cFetched = 123;
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain 1 elements, pcFetched==NULL, with 1 element in the enum
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1,&rgpICP[0],NULL),S_OK);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[0]));
|
|
SAFE_RELEASE(rgpICP[0]);
|
|
|
|
//Reset enum position
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain 2 elements, pcFetched==NULL, with 1 element in the enum
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(2, rgpICP, NULL),E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(rgpICP[0]);
|
|
SAFE_RELEASE(rgpICP[1]);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[1, NULL, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_7()
|
|
{
|
|
//obtain 1 elements, E_POINTER
|
|
//rgpcd==NULL - E_POINTER
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, NULL, NULL), E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(8)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[ULONG_MAX, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_8()
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 123;
|
|
|
|
//Can't really do ULONG_MAX as the variation suggests since I have to
|
|
//alloc the array passed in. But I can do something large enough 1000?
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP()+1000, IConnectionPoint*);
|
|
memset(rgpICP, 0, (pCSource(0)->GetCountCP()+1000) * sizeof(IConnectionPoint*));
|
|
rgpICP[pCSource(0)->GetCountCP()] = INVALID(IConnectionPoint*);
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain N+1 elements, S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(pCSource(0)->GetCountCP()+1000, rgpICP, &cFetched), S_FALSE);
|
|
TESTC(cFetched == pCSource(0)->GetCountCP());
|
|
TESTC(VerifyConnectionPoints(cFetched, rgpICP));
|
|
TESTC(rgpICP[pCSource(0)->GetCountCP()]==INVALID(IConnectionPoint*) || rgpICP[pCSource(0)->GetCountCP()]==NULL);
|
|
|
|
CLEANUP:
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(9)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[valid, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_9()
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 123;
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP()+1, IConnectionPoint*);
|
|
memset(rgpICP, 0, (pCSource(0)->GetCountCP()+1) * sizeof(IConnectionPoint*));
|
|
rgpICP[pCSource(0)->GetCountCP()] = INVALID(IConnectionPoint*);
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain 1 element
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &rgpICP[0], &cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[0]));
|
|
SAFE_RELEASE(rgpICP[0]);
|
|
|
|
//obtain N elements, S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(pCSource(0)->GetCountCP(), rgpICP, &cFetched), S_FALSE);
|
|
TESTC(cFetched==pCSource(0)->GetCountCP()-1);
|
|
TESTC(VerifyConnectionPoints(cFetched, rgpICP));
|
|
TESTC(rgpICP[pCSource(0)->GetCountCP()]==INVALID(IConnectionPoint*));
|
|
|
|
CLEANUP:
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(10)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[0, valid, NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_10()
|
|
{
|
|
TBEGIN
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG cFetched = 123;
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//(0, valid, NULL) - cConnections==0 - E_INVALIDARG
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(0, &pICP, NULL),E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(11)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[1, NULL, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_11()
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 123;
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//(1, NULL, valid) - rgpcn==NULL - E_INVALIDARG
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, NULL, &cFetched), E_POINTER);
|
|
TESTC(cFetched==0);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(12)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[N+1, valid, valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_12()
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 123;
|
|
ULONG cPoints = pCSource(0)->GetCountCP();
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(cPoints+1, IConnectionPoint*);
|
|
memset(rgpICP, 0, (cPoints+1) * sizeof(IConnectionPoint*));
|
|
rgpICP[cPoints] = INVALID(IConnectionPoint*);
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain N+1 elements, S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(cPoints+1, rgpICP, &cFetched), S_FALSE);
|
|
TESTC(cFetched == cPoints);
|
|
TESTC(VerifyConnectionPoints(cFetched, rgpICP));
|
|
TESTC(rgpICP[cPoints]==INVALID(IConnectionPoint*) || rgpICP[cPoints]==NULL);
|
|
|
|
CLEANUP:
|
|
FreeConnectionPoints(cPoints, rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(13)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[seperately]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_13()
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 123;
|
|
ULONG cPoints = pCSource(0)->GetCountCP();
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(cPoints+1, IConnectionPoint*);
|
|
memset(rgpICP, 0, (cPoints+1) * sizeof(IConnectionPoint*));
|
|
rgpICP[cPoints] = INVALID(IConnectionPoint*);
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain 1 element
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &rgpICP[0], &cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[0]));
|
|
SAFE_RELEASE(rgpICP[0]);
|
|
|
|
//obtain N elements, S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(cPoints, rgpICP, &cFetched), S_FALSE);
|
|
TESTC(cFetched==cPoints-1);
|
|
TESTC(VerifyConnectionPoints(cFetched, rgpICP));
|
|
TESTC(rgpICP[cPoints]==INVALID(IConnectionPoint*));
|
|
|
|
CLEANUP:
|
|
FreeConnectionPoints(cPoints, rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(14)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[group]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_14()
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 123;
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP(), IConnectionPoint*);
|
|
memset(rgpICP, 0, pCSource(0)->GetCountCP() * sizeof(IConnectionPoint*));
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain N elements, S_OK
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(pCSource(0)->GetCountCP(), rgpICP, &cFetched), S_OK);
|
|
TESTC(cFetched == pCSource(0)->GetCountCP());
|
|
TESTC(VerifyConnectionPoints(cFetched, rgpICP));
|
|
|
|
CLEANUP:
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(15)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Next[sequence]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_15()
|
|
{
|
|
TBEGIN
|
|
ULONG cFetched = 123;
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP()+1, IConnectionPoint*);
|
|
memset(rgpICP, 0, (pCSource(0)->GetCountCP()+1) * sizeof(IConnectionPoint*));
|
|
|
|
//Obtain the Enumerator over the CPs
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//obtain 1 element
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &rgpICP[0], &cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[0]));
|
|
SAFE_RELEASE(rgpICP[0]);
|
|
|
|
//obtain N elements, S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(pCSource(0)->GetCountCP(), rgpICP, &cFetched), S_FALSE);
|
|
TESTC(cFetched == pCSource(0)->GetCountCP()-1);
|
|
TESTC(VerifyConnectionPoints(cFetched, rgpICP));
|
|
|
|
CLEANUP:
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(16)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Skip[0]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_16()
|
|
{
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//Call skip(NULL) - S_OK
|
|
//cConnections==0 - E_INVALIDARG
|
|
TESTC_(pCSource(0)->pIEnumCP()->Skip(0),E_INVALIDARG);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(17)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Skip[ULONG_MAX]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_17()
|
|
{
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG cFetched = 123;
|
|
|
|
//Skip ULONG_MAX should return S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
TESTC_(pCSource(0)->pIEnumCP()->Skip(ULONG_MAX), S_FALSE);
|
|
|
|
//Move position away from head
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1,&pICP,&cFetched),S_OK);
|
|
TESTC(cFetched==1)
|
|
TESTC(VerifyConnectionPoints(cFetched, &pICP));
|
|
|
|
//Skip ULONG_MAX should return S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Skip(ULONG_MAX), S_FALSE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(18)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Skip[N]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_18()
|
|
{
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG cFetched = 123;
|
|
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//Call skip[N] - S_FALSE
|
|
TESTC_(pCSource(0)->pIEnumCP()->Skip(pCSource(0)->GetCountCP()),S_OK);
|
|
|
|
//Verify at tail now...
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1,&pICP,&cFetched),S_FALSE);
|
|
TESTC(pICP==NULL && cFetched==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(19)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Skip[N+1]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_19()
|
|
{
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG cFetched = 123;
|
|
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//Call skip - S_OK
|
|
TESTC_(pCSource(0)->pIEnumCP()->Skip(pCSource(0)->GetCountCP()+1),S_FALSE);
|
|
|
|
//Verify at tail now...
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1,&pICP,&cFetched),S_FALSE);
|
|
TESTC(pICP==NULL && cFetched==0);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(20)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Skip[N-1]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_20()
|
|
{
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG cFetched = 123;
|
|
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//Call skip - E_INVALIDARG
|
|
//cConnections==0 - E_INVALIDARG
|
|
TESTC_(pCSource(0)->pIEnumCP()->Skip(0),E_INVALIDARG);
|
|
|
|
//Verify still at head...
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1,&pICP,&cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyConnectionPoints(1, &pICP));
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(21)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Clone[NULL]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_21()
|
|
{
|
|
//Clone...
|
|
TESTC_(pCSource(0)->pIEnumCP()->Clone(NULL), E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(22)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc EnumCP::Clone[valid]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_22()
|
|
{
|
|
IEnumConnectionPoints* pIEnumCPClone = NULL;
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG i,cFetched = 123;
|
|
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//Clone(valid) - S_OK
|
|
TESTC_(pCSource(0)->pIEnumCP()->Clone(&pIEnumCPClone),S_OK);
|
|
TESTC(pIEnumCPClone != NULL);
|
|
|
|
//Verify clone
|
|
for(i=0; i<pCSource(0)->GetCountCP(); i++)
|
|
{
|
|
TESTC_(pIEnumCPClone->Next(1,&pICP,&cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyConnectionPoints(1,&pICP));
|
|
SAFE_RELEASE(pICP);
|
|
}
|
|
|
|
//Try to obtain 1 more
|
|
TESTC_(pIEnumCPClone->Next(1,&pICP,&cFetched),S_FALSE);
|
|
TESTC(cFetched==0 && pICP==NULL);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIEnumCPClone);
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(23)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Sequence - EnumCP sequence testing
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_23()
|
|
{
|
|
TBEGIN
|
|
|
|
// rgpIEnumConnections[0] - Enum
|
|
// rgpIEnumConnections[1] - Clone of Enum[0]
|
|
// rgpIEnumConnections[2] - Clone of Enum[1]
|
|
IEnumConnectionPoints* rgpIEnumCP[3] = {NULL,NULL,NULL};
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP()+1, IConnectionPoint*);
|
|
memset(rgpICP, 0, (pCSource(0)->GetCountCP()+1) * sizeof(IConnectionPoint*));
|
|
ULONG i,cFetched = 0;
|
|
|
|
//Obtain the enums
|
|
TESTC_(pCSource(0)->pICPC()->EnumConnectionPoints(&rgpIEnumCP[0]),S_OK);
|
|
TESTC_(rgpIEnumCP[0]->Clone(&rgpIEnumCP[1]),S_OK);
|
|
TESTC_(rgpIEnumCP[1]->Clone(&rgpIEnumCP[2]),S_OK);
|
|
|
|
//Reset the enums
|
|
for(i=0; i<3; i++)
|
|
TESTC_(rgpIEnumCP[i]->Reset(),S_OK);
|
|
|
|
//cConnections==0 - E_INVALIDARG
|
|
TESTC_(rgpIEnumCP[0]->Next(0,&rgpICP[0],&cFetched),E_INVALIDARG);
|
|
TESTC(cFetched == 0);
|
|
|
|
//Next 1
|
|
TESTC_(rgpIEnumCP[1]->Next(1,&rgpICP[0],&cFetched),S_OK);
|
|
TESTC(cFetched == 1)
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[0]));
|
|
SAFE_RELEASE(rgpICP[0]);
|
|
|
|
//Next N
|
|
cFetched = 123;
|
|
TESTC_(rgpIEnumCP[2]->Next(pCSource(0)->GetCountCP(), rgpICP, &cFetched),S_OK);
|
|
TESTC(cFetched == pCSource(0)->GetCountCP());
|
|
TESTC(VerifyConnectionPoints(cFetched, rgpICP));
|
|
|
|
//Increment the position
|
|
TESTC_(rgpIEnumCP[0]->Skip(pCSource(0)->GetCountCP()),S_OK);
|
|
|
|
//Call skip from current location, should all return S_FALSE
|
|
TESTC_(rgpIEnumCP[0]->Skip(1),S_FALSE);
|
|
TESTC_(rgpIEnumCP[1]->Skip(pCSource(0)->GetCountCP()), S_FALSE);
|
|
TESTC_(rgpIEnumCP[2]->Skip(1),S_FALSE);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(rgpIEnumCP[0]);
|
|
SAFE_RELEASE(rgpIEnumCP[1]);
|
|
SAFE_RELEASE(rgpIEnumCP[2]);
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(24)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Regression test case for MDAC bug 73957
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCEnumConnectionPoints::Variation_24()
|
|
{
|
|
ULONG i, j, cFetched = 123;
|
|
HRESULT hr;
|
|
IConnectionPoint* pICP1 = NULL;
|
|
IConnectionPoint* pICP2 = NULL;
|
|
BOOL fFind = FALSE;
|
|
IID iid;
|
|
IID rgIIDs[3];
|
|
|
|
rgIIDs[0] = IID_IRowsetNotify;
|
|
rgIIDs[1] = IID_IDBAsynchNotify;
|
|
rgIIDs[2] = IID_IRowPositionChange;
|
|
|
|
// verify that if FindConnectionPoint finds a CP this CP can also be found through EnumConnectionPoints
|
|
// the array m_SupportedCP[] contains
|
|
for (i=0; i<3; i++)
|
|
{
|
|
TEST2C_(hr=pCSource(0)->pICPC()->FindConnectionPoint(rgIIDs[i], &pICP1), S_OK, CONNECT_E_NOCONNECTION)
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
TESTC(pICP1!=NULL);
|
|
|
|
//Reset the Enum
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
fFind = FALSE;
|
|
//Try to find CP in the container
|
|
for(j=0; j<pCSource(0)->GetCountCP(); j++)
|
|
{
|
|
//Obtain the first Element
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1,&pICP2,&cFetched),S_OK);
|
|
TESTC(cFetched==1 && pICP2);
|
|
|
|
//get the IID of the returned CP
|
|
TESTC_(pICP2->GetConnectionInterface(&iid),S_OK);
|
|
SAFE_RELEASE(pICP2);
|
|
|
|
if (iid==rgIIDs[i])
|
|
{
|
|
fFind = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
TESTC(fFind);
|
|
}
|
|
SAFE_RELEASE(pICP1);
|
|
}
|
|
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP1);
|
|
SAFE_RELEASE(pICP2);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCEnumConnectionPoints::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCFindConnectionPoint)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCFindConnectionPoint - Test IConnectionPointInterface::FindConnectionPoint
|
|
//| Created: 02/29/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCFindConnectionPoint::Init()
|
|
{
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(m_dwTestCaseParam2));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - verify reference count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCFindConnectionPoint::Variation_1()
|
|
{
|
|
//Verify connections / reference count
|
|
TESTC(VerifyRefCount() && VerifyNoConnection());
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Empty
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCFindConnectionPoint::Variation_2()
|
|
{
|
|
// this variation is a dublicate of V2 TCEnumConnectionPoints => commented out
|
|
return TEST_SKIPPED;
|
|
|
|
/*
|
|
IID iid;
|
|
ULONG i,cFetched = 123;
|
|
|
|
IConnectionPoint* pICP2 = NULL;
|
|
IConnectionPoint** rgpICP = PROVIDER_ALLOC_(pCSource(0)->GetCountCP(), IConnectionPoint*);
|
|
memset(rgpICP, 0, pCSource(0)->GetCountCP() * sizeof(IConnectionPoint*));
|
|
|
|
//Reset the Enum
|
|
TESTC_(pCSource(0)->pIEnumCP()->Reset(),S_OK);
|
|
|
|
//For each CP in the container, verify that Get(IID) == Find(IID)
|
|
for(i=0; i<pCSource(0)->GetCountCP(); i++)
|
|
{
|
|
//Obtain the first Element
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1,&rgpICP[i],&cFetched),S_OK);
|
|
TESTC(cFetched==1);
|
|
TESTC(VerifyConnectionPoints(1, &rgpICP[i]));
|
|
|
|
//get the IID of the returned CP
|
|
TESTC_(rgpICP[i]->GetConnectionInterface(&iid),S_OK);
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(iid, &pICP2), S_OK);
|
|
|
|
//Verify it matches over already obtained pPC
|
|
TESTC(VerifyEqualInterface(rgpICP[i], pICP2));
|
|
SAFE_RELEASE(pICP2);
|
|
}
|
|
|
|
//Verify were at the end
|
|
TESTC_(pCSource(0)->pIEnumCP()->Next(1, &pICP2, &cFetched),S_FALSE);
|
|
TESTC(cFetched == 0);
|
|
|
|
//Verify ConnectionnPoints returned
|
|
TESTC(VerifyConnectionPoints(pCSource(0)->GetCountCP(), rgpICP));
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP2);
|
|
FreeConnectionPoints(pCSource(0)->GetCountCP(), rgpICP);
|
|
PROVIDER_FREE(rgpICP);
|
|
VerifyRefCount();
|
|
TRETURN
|
|
*/
|
|
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc General - call repeatedly and verify reference count
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCFindConnectionPoint::Variation_3()
|
|
{
|
|
TBEGIN
|
|
IConnectionPoint* rgpICP[12];
|
|
ULONG cRefCount = GetRefCount(pCSource(0)->GetCP());
|
|
ULONG cAddRef = 0;
|
|
memset(rgpICP, 0, sizeof(rgpICP));
|
|
ULONG i=0;
|
|
//Call FindConnectionPoint repeaditly 10 times
|
|
for(i=0; i<10; i++)
|
|
{
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(pCSource(0)->GetIID(), &rgpICP[i]),S_OK);
|
|
|
|
//verify returned pICP with our CP, (which is a IRowsetNotifyCP)
|
|
if (VerifyEqualInterface(rgpICP[i], pCSource(0)->GetCP()))
|
|
cAddRef++;
|
|
}
|
|
|
|
//Verify Reference count
|
|
TESTC(VerifyRefCounts(GetRefCount(pCSource(0)->GetCP()), cRefCount+cAddRef));
|
|
|
|
//Now Release 2 and verify
|
|
for(i=0; i<2; i++)
|
|
{
|
|
if (VerifyEqualInterface(rgpICP[i], pCSource(0)->GetCP()))
|
|
cAddRef--;
|
|
SAFE_RELEASE(rgpICP[i]);
|
|
}
|
|
|
|
TESTC(VerifyRefCounts(GetRefCount(pCSource(0)->GetCP()), cRefCount+cAddRef));
|
|
|
|
//Call Find 2 more times
|
|
for(i=0; i<2; i++)
|
|
{
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(pCSource(0)->GetIID(), &rgpICP[i]),S_OK);
|
|
|
|
//verify returned pICP with our CP, (which is a IRowsetNotifyCP)
|
|
if (VerifyEqualInterface(rgpICP[i], pCSource(0)->GetCP()))
|
|
cAddRef++;
|
|
}
|
|
TESTC(VerifyRefCounts(GetRefCount(pCSource(0)->GetCP()),cRefCount+cAddRef));
|
|
|
|
CLEANUP:
|
|
//Release remaining
|
|
for(i=0; i<10; i++)
|
|
SAFE_RELEASE(rgpICP[i]);
|
|
|
|
//Verify Reference count
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - riid NULL CONNECT_E_NOCONNECTION
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCFindConnectionPoint::Variation_4()
|
|
{
|
|
TBEGIN
|
|
|
|
IConnectionPoint* pICP = NULL;
|
|
GUID NULL_RIID = { NULL, NULL, NULL, NULL };
|
|
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(NULL_RIID,&pICP),CONNECT_E_NOCONNECTION);
|
|
TESTC(pICP == NULL);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - ppICP E_POINTER
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCFindConnectionPoint::Variation_5()
|
|
{
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(pCSource(0)->GetIID(), NULL), E_POINTER);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Boundary/NULL - verify valid / invalid CP
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCFindConnectionPoint::Variation_6()
|
|
{
|
|
TBEGIN
|
|
|
|
const IID* SupportedCP[] = { &pCSource(0)->GetIID(),
|
|
NULL };
|
|
|
|
const IID* InSupportedCP[] = { &IID_IConnectionPoint,
|
|
&IID_IConnectionPointContainer,
|
|
&IID_IAccessor,
|
|
NULL };
|
|
|
|
IConnectionPoint* pICP = NULL;
|
|
ULONG i=0;
|
|
//TEST_ valid IID's
|
|
for(i=0; SupportedCP[i]; i++)
|
|
{
|
|
//verify valid IID
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(*SupportedCP[i],&pICP),S_OK);
|
|
|
|
//TEST_ returned pICP with our CP
|
|
TESTC(VerifyEqualICPoint(pICP, pCSource(0)->GetCP()));
|
|
SAFE_RELEASE(pICP);
|
|
}
|
|
|
|
//TEST_ Invalid IID's
|
|
for(i=0; InSupportedCP[i]; i++)
|
|
{
|
|
//verify Invalid IID
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(*InSupportedCP[i],&pICP),CONNECT_E_NOCONNECTION);
|
|
TESTC(pICP == NULL);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
VerifyRefCount();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(7)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Multi-User - 2 Sinks / 1 Source verify IID returned
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCFindConnectionPoint::Variation_7()
|
|
{
|
|
TBEGIN
|
|
|
|
IConnectionPoint* pICP = NULL;
|
|
IID iid;
|
|
|
|
//Find IID_IRowsetNotify CP
|
|
TESTC_(pCSource(0)->pICPC()->FindConnectionPoint(pCSource(0)->GetIID(), &pICP),S_OK);
|
|
|
|
//TEST_ returned pICP with our CP, (which is a IRowsetNotifyCP)
|
|
TESTC(VerifyEqualICPoint(pICP, pCSource(0)->GetCP()));
|
|
|
|
//Now wire up 2 sinks using the newly found CP, verify connection
|
|
TESTC(AdviseNum(2,1));
|
|
|
|
//Verify same IID even when connections are established
|
|
TESTC_(pICP->GetConnectionInterface(&iid),S_OK);
|
|
|
|
TESTC(iid == pCSource(0)->GetIID());
|
|
SAFE_RELEASE(pICP);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pICP);
|
|
//Now unadvise the connections before existing
|
|
UnadviseAll();
|
|
TRETURN
|
|
}
|
|
// }}
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCFindConnectionPoint::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCNotReEntrant)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCNotReEntrant - Test all interfaces that will return DB_E_NOTREENTRANT
|
|
//| Created: 03/20/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCNotReEntrant::Init()
|
|
{
|
|
//this test case is specific for Rowset object and IRowsetNotify
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(IID_IRowsetNotify));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// IRowset - reentrantcy methods
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT TCNotReEntrant::RE_AddRefRows(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
//But should fail since those rows are already released
|
|
ULONG* rgRefCount = PROVIDER_ALLOC_(cRows,ULONG);
|
|
DBROWSTATUS* rgRowStatus = PROVIDER_ALLOC_(cRows,DBROWSTATUS);
|
|
HRESULT hr = S_OK;
|
|
|
|
//This method (RE_AddRefRows) is called from within ReleaseRows notification
|
|
//This will cause an error if the provider gets rid of row handles, otherwise
|
|
//will be success if row handles are always arround (never go to 0 refcount).
|
|
TEST2C_(hr = pIRowset->AddRefRows(cRows,rghRows,rgRefCount,rgRowStatus), S_OK, DB_E_ERRORSOCCURRED);
|
|
|
|
//Verify return results
|
|
if(hr==S_OK)
|
|
{
|
|
TESTC(VerifyRefCounts(cRows, rgRefCount, 2));
|
|
TESTC(VerifyArray(cRows, rgRowStatus, DBROWSTATUS_S_OK));
|
|
}
|
|
else
|
|
{
|
|
TESTC(VerifyRefCounts(cRows,rgRefCount,0));
|
|
TESTC(VerifyArray(cRows,rgRowStatus,DBROWSTATUS_E_INVALID));
|
|
}
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rgRefCount);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_GetData(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
//Call GetData from within the Listener
|
|
HACCESSOR hAccessor = pCRowset->m_hAccessor;
|
|
void* pData = pCRowset->m_pData;
|
|
HRESULT hr = S_OK;
|
|
|
|
//GetData should be totaly reentrant.
|
|
TESTC_(hr = pIRowset->GetData(rghRows[0],hAccessor,pData),S_OK);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_GetNextRows(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
DBCOUNTITEM cRowsObtained = MAXDBCOUNTITEM;
|
|
HROW* rghRowsObtained = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowset->GetNextRows(NULL,0,1,&cRowsObtained,&rghRowsObtained);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
//Should NULL output params on error
|
|
if(hr==S_OK)
|
|
{
|
|
TESTC(cRowsObtained == 1);
|
|
TESTC(rghRowsObtained != NULL && rghRowsObtained[0]!=DB_NULL_HROW);
|
|
}
|
|
else
|
|
{
|
|
TESTC(cRowsObtained == 0);
|
|
TESTC(rghRowsObtained == NULL);
|
|
}
|
|
|
|
CLEANUP:
|
|
PROVIDER_FREE(rghRowsObtained);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_ReleaseRows(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
HRESULT hr = S_OK;
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowset->ReleaseRows(cRows,rghRows,NULL,NULL,NULL);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_RestartPosition(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
HRESULT hr = S_OK;
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowset->RestartPosition(NULL);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// IRowsetChange - reentrantcy methods
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT TCNotReEntrant::RE_DeleteRows(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
//But should fail since those rows are already released
|
|
DBROWSTATUS* rgRowStatus = PROVIDER_ALLOC_(cRows,DBROWSTATUS);
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetChange interface
|
|
IRowsetChange* pIRowsetChange = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetChange,(void**)&pIRowsetChange),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetChange->DeleteRows(NULL,cRows,rghRows,rgRowStatus);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
//Verify Results
|
|
if(hr==S_OK)
|
|
{
|
|
for(ULONG i=0; i<cRows; i++)
|
|
TESTC(rgRowStatus[i]==DBROWSTATUS_S_OK);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_InsertRow(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
//Call InsertRow from within the Listener
|
|
HACCESSOR hAccessor = pCRowset->m_hAccessor;
|
|
void* pData = pCRowset->m_pData;
|
|
HROW hRow = INVALID(HROW);
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetChange interface
|
|
IRowsetChange* pIRowsetChange = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetChange,(void**)&pIRowsetChange),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetChange->InsertRow(NULL,hAccessor,pData,&hRow);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
//Verify Results
|
|
if(hr==S_OK)
|
|
{
|
|
TESTC(hRow != DB_NULL_HROW);
|
|
}
|
|
else
|
|
{
|
|
TESTC(hRow == DB_NULL_HROW);
|
|
}
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_SetData(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
HACCESSOR hAccessor = pCRowset->m_hAccessor;
|
|
void* pData = pCRowset->m_pData;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetChange interface
|
|
IRowsetChange* pIRowsetChange = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetChange,(void**)&pIRowsetChange),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetChange->SetData(rghRows[0],hAccessor,pData);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetChange);
|
|
return hr;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// IRowsetUpdate - reentrantcy methods
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT TCNotReEntrant::RE_GetOriginalData(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
HACCESSOR hAccessor = pCRowset->m_hAccessor;
|
|
void* pData = pCRowset->m_pData;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetUpdate interface
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetUpdate,(void**)&pIRowsetUpdate),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetUpdate->GetOriginalData(rghRows[0],hAccessor,pData);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_GetPendingRows(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
DBCOUNTITEM cPendingRows = MAXDBCOUNTITEM;
|
|
HROW* rgPendingRows = NULL;
|
|
DBROWSTATUS* rgPendingStatus = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetUpdate interface
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetUpdate,(void**)&pIRowsetUpdate),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetUpdate->GetPendingRows(NULL,DBPENDINGSTATUS_ALL,&cPendingRows,&rgPendingRows,&rgPendingStatus);
|
|
TESTC(hr==S_OK || hr==S_FALSE || hr==DB_E_NOTREENTRANT);
|
|
|
|
//Verify Results
|
|
TESTC(cPendingRows != ULONG_MAX);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
PROVIDER_FREE(rgPendingRows);
|
|
PROVIDER_FREE(rgPendingStatus);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_GetRowStatus(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
DBROWSTATUS* rgPendingStatus = PROVIDER_ALLOC_(cRows,DBROWSTATUS);
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetUpdate interface
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetUpdate,(void**)&pIRowsetUpdate),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetUpdate->GetRowStatus(NULL,cRows,rghRows,rgPendingStatus);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
PROVIDER_FREE(rgPendingStatus);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT TCNotReEntrant::RE_Undo(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
DBCOUNTITEM cRowsUndone = MAXDBCOUNTITEM;
|
|
HROW* rgRowsUndone = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetUpdate interface
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetUpdate,(void**)&pIRowsetUpdate),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetUpdate->Undo(NULL,cRows,rghRows,&cRowsUndone,&rgRowsUndone,&rgRowStatus);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
//Verify return results
|
|
TESTC(cRowsUndone != ULONG_MAX);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
PROVIDER_FREE(rgRowsUndone);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
return hr;
|
|
}
|
|
|
|
HRESULT TCNotReEntrant::RE_Update(CRowset* pCRowset, IRowset* pIRowset, ULONG cRows, const HROW rghRows[], ULONG cColumns, const ULONG rgColumns[])
|
|
{
|
|
ASSERT(pCRowset && pIRowset && cRows && rghRows);
|
|
|
|
DBCOUNTITEM cRowsUpdated = MAXDBCOUNTITEM;
|
|
HROW* rgRowsUpdated = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
//Obtain IRowsetUpdate interface
|
|
IRowsetUpdate* pIRowsetUpdate = NULL;
|
|
TESTC_(QI(pIRowset,IID_IRowsetUpdate,(void**)&pIRowsetUpdate),S_OK);
|
|
|
|
//Should either succeed (Allows this method to be reentrant) or fail with DB_E_NOTREENTRANT
|
|
hr = pIRowsetUpdate->Update(NULL,cRows,rghRows,&cRowsUpdated,&rgRowsUpdated,&rgRowStatus);
|
|
TESTC(hr==S_OK || hr==DB_E_NOTREENTRANT);
|
|
|
|
//Verify return results
|
|
TESTC(cRowsUpdated != ULONG_MAX);
|
|
|
|
CLEANUP:
|
|
SAFE_RELEASE(pIRowsetUpdate);
|
|
PROVIDER_FREE(rgRowsUpdated);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
return hr;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IRowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotReEntrant::Variation_1()
|
|
{
|
|
TBEGIN
|
|
DWORD dwCookie = 0;
|
|
CListener* pCListener = NULL;
|
|
|
|
//Create Rowset
|
|
CRowset Rowset;
|
|
TESTC_PROVIDER(Rowset.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, Rowset());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie), S_OK);
|
|
|
|
//Try ReleaseRows -> AddRefRows
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_RELEASE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_AddRefRows, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_RELEASE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try GetNextRows -> GetData
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_GetData, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try GetNextRows -> GetNextRows
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_GetNextRows, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try ReleaseRows -> ReleaseRows
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_RELEASE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_ReleaseRows, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_RELEASE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try GetNextRows -> RestartPosition
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_RestartPosition, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IRowsetChange
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotReEntrant::Variation_2()
|
|
{
|
|
TBEGIN
|
|
DWORD dwCookie = 0;
|
|
CListener* pCListener = NULL;
|
|
|
|
//Create Rowset
|
|
CRowset Rowset;
|
|
Rowset.SetProperty(DBPROP_IRowsetChange);
|
|
TESTC_PROVIDER(Rowset.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, Rowset());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Try ReleaseRows -> DeleteRow
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_DeleteRows, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Need to setup the SetData/InsertRow pData buffer
|
|
TESTC(Rowset.MakeRowData(&Rowset.m_pData));
|
|
|
|
//Try GetNextRows -> InsertRow
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_InsertRow, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Need to setup the SetData/InsertRow pData buffer
|
|
TESTC(Rowset.MakeRowData(&Rowset.m_pData));
|
|
|
|
//Try GetNextRows -> SetData
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_SetData, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc IRowsetUpdate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotReEntrant::Variation_3()
|
|
{
|
|
TBEGIN
|
|
DWORD dwCookie = 0;
|
|
CListener* pCListener = NULL;
|
|
|
|
//Create Rowset
|
|
CRowset Rowset;
|
|
Rowset.SetProperty(DBPROP_IRowsetUpdate);
|
|
TESTC_PROVIDER(Rowset.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, Rowset());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Try ReleaseRows -> GetOriginalData
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_GetOriginalData, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try GetNextRows -> GetPendingRows
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_GetPendingRows, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try GetNextRows -> GetRowStatus
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_GetRowStatus, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try GetNextRows -> Undo
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_Undo, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try GetNextRows -> Update
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC(pCListener->SetReEntrantcy(DBREASON_ROW_ACTIVATE, DBEVENTPHASE_DIDEVENT, TCNotReEntrant::RE_Update, &Rowset));
|
|
TESTC_(pCListener->CauseNotification(DBREASON_ROW_ACTIVATE),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCNotReEntrant::Terminate()
|
|
{
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCZombie)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCZombie - Test the zombie cases for ICPC/ICP
|
|
//| Created: 07/22/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCZombie::Init()
|
|
{
|
|
TBEGIN
|
|
m_cPropSets = 0;
|
|
m_rgPropSets = NULL;
|
|
|
|
if (ROWSET_INTERFACE != m_dwTestCaseParam1 || IID_IRowsetNotify != m_dwTestCaseParam2)
|
|
{
|
|
TOUTPUT_LINE(L"This test case only run for Rowset when IRowsetNotify is supported");
|
|
return TEST_SKIPPED;
|
|
}
|
|
|
|
CRowsetSource* pSource = new CRowsetSource(IID_IRowsetNotify);
|
|
TESTC_PROVIDER(pSource->CreateSource());
|
|
TESTC_PROVIDER(pSource->IsSupportedCP(IID_IRowsetNotify));
|
|
SAFE_DELETE(pSource);
|
|
|
|
// {{ TCW_INIT_BASECLASS_CHECK
|
|
if(TCTransaction::Init())
|
|
// }}
|
|
{
|
|
//Set Properties
|
|
//If ICPC is not supported, were done testing
|
|
TEST_PROVIDER(SetSupportedProperty(DBPROP_IConnectionPointContainer,DBPROPSET_ROWSET,&m_cPropSets,&m_rgPropSets));
|
|
|
|
//register interface to be tested
|
|
if(RegisterInterface(ROWSET_INTERFACE, IID_IRowset))
|
|
return TRUE;
|
|
}
|
|
|
|
//Not all providers have to support transactions
|
|
//If a required interface, an error would have been posted by VerifyInterface
|
|
TEST_PROVIDER(m_pITransactionLocal != NULL);
|
|
|
|
CLEANUP:
|
|
SAFE_DELETE(pSource);
|
|
TRETURN;
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - ABORT with fRetaining == TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_1()
|
|
{
|
|
IRowset* pIRowset = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW* rghRow = NULL;
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowset,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowset!=NULL);
|
|
|
|
//Establish a listener for the rowset
|
|
pCListener = new CListener(IID_IRowsetNotify, pIRowset);
|
|
pCListener->AddRef();
|
|
|
|
//Obtain the ABORTPRESERVE flag and adjust ExpectedHr
|
|
if(m_fAbortPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Advise the connection
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Abort the Transaction with fRetaining==TRUE
|
|
TESTC(GetAbort(TRUE));
|
|
|
|
//Obtain the first row
|
|
TESTC_(pIRowset->GetNextRows(NULL,0,ONE_ROW,&cRowsObtained,&rghRow),ExpectedHr);
|
|
|
|
//Check for the notifcation
|
|
if(m_fAbortPreserve)
|
|
TESTC(pCListener->GetTimesNotified() > 0) //notifcation should have succedded
|
|
else
|
|
TESTC(pCListener->GetTimesNotified() == 0) //rowset is zombied
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise the connection
|
|
if(pCListener && dwCookie)
|
|
pCListener->Unadvise(dwCookie);
|
|
|
|
//Release the rows
|
|
if(pIRowset && rghRow)
|
|
pIRowset->ReleaseRows(ONE_ROW,rghRow,NULL,NULL,NULL);
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
CleanUpTransaction(S_OK);
|
|
PROVIDER_FREE(rghRow);
|
|
SAFE_DELETE(pCListener); //CleanUpTransaction will call pCListener->Release
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - ABORT with fRetaining == FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_2()
|
|
{
|
|
IRowset* pIRowset = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW* rghRow = NULL;
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowset,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowset!=NULL);
|
|
|
|
//Establish a listener for the rowset
|
|
pCListener = new CListener(IID_IRowsetNotify, pIRowset);
|
|
pCListener->AddRef();
|
|
|
|
//Obtain the ABORTPRESERVE flag and adjust ExpectedHr
|
|
if(m_fAbortPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Advise the connection
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Abort the Transaction with fRetaining==FALSE
|
|
TESTC(GetAbort(FALSE));
|
|
|
|
//Obtain the first row
|
|
TESTC_(pIRowset->GetNextRows(NULL,0,ONE_ROW,&cRowsObtained,&rghRow),ExpectedHr);
|
|
|
|
//Check for the notifcation
|
|
if(m_fAbortPreserve)
|
|
TESTC(pCListener->GetTimesNotified() > 0) //notifcation should have succedded
|
|
else
|
|
TESTC(pCListener->GetTimesNotified() == 0) //rowset is zombied
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise the connection
|
|
if(pCListener && dwCookie)
|
|
pCListener->Unadvise(dwCookie);
|
|
|
|
//Release the rows
|
|
if(pIRowset && rghRow)
|
|
pIRowset->ReleaseRows(ONE_ROW,rghRow,NULL,NULL,NULL);
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
CleanUpTransaction(XACT_E_NOTRANSACTION); //No longer in a transaction
|
|
PROVIDER_FREE(rghRow);
|
|
SAFE_DELETE(pCListener); //CleanUpTransaction will call pCListener->Release
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - COMMIT with fRetaining == TRUE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_3()
|
|
{
|
|
IRowset* pIRowset = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW* rghRow = NULL;
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowset,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowset!=NULL);
|
|
|
|
//Establish a listener for the rowset
|
|
pCListener = new CListener(IID_IRowsetNotify, pIRowset);
|
|
pCListener->AddRef();
|
|
|
|
//Obtain the COMMITPRESERVE flag and adjust ExpectedHr
|
|
if(m_fCommitPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Advise the connection
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Abort the Transaction with fRetaining==TRUE
|
|
TESTC(GetCommit(TRUE));
|
|
|
|
//Obtain the first row
|
|
TESTC_(pIRowset->GetNextRows(NULL,0,ONE_ROW,&cRowsObtained,&rghRow),ExpectedHr);
|
|
|
|
//Check for the notifcation
|
|
if(m_fCommitPreserve)
|
|
TESTC(pCListener->GetTimesNotified() > 0) //notifcation should have succedded
|
|
else
|
|
TESTC(pCListener->GetTimesNotified() == 0) //rowset is zombied
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise the connection
|
|
if(pCListener && dwCookie)
|
|
pCListener->Unadvise(dwCookie);
|
|
|
|
//Release the rows
|
|
if(pIRowset && rghRow)
|
|
pIRowset->ReleaseRows(ONE_ROW,rghRow,NULL,NULL,NULL);
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
CleanUpTransaction(S_OK);
|
|
PROVIDER_FREE(rghRow);
|
|
SAFE_DELETE(pCListener); //CleanUpTransaction will call pCListener->Release
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Zombie - COMMIT with fRetaining == FALSE
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCZombie::Variation_4()
|
|
{
|
|
IRowset* pIRowset = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
DBCOUNTITEM cRowsObtained = 0;
|
|
HROW* rghRow = NULL;
|
|
HRESULT ExpectedHr = E_UNEXPECTED;
|
|
|
|
//Start the Transaction
|
|
//And obtain the IOpenRowset interface
|
|
TESTC(StartTransaction(USE_SUPPORTED_SELECT_ALLFROMTBL,(IUnknown**)&pIRowset,m_cPropSets,m_rgPropSets));
|
|
TESTC(pIRowset!=NULL);
|
|
|
|
//Establish a listener for the rowset
|
|
pCListener = new CListener(IID_IRowsetNotify, pIRowset);
|
|
pCListener->AddRef();
|
|
|
|
//Obtain the COMMITPRESERVE flag and adjust ExpectedHr
|
|
if(m_fCommitPreserve)
|
|
ExpectedHr = S_OK;
|
|
|
|
//Advise the connection
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Abort the Transaction with fRetaining==TRUE
|
|
TESTC(GetCommit(FALSE));
|
|
|
|
//Obtain the first row
|
|
TESTC_(pIRowset->GetNextRows(NULL,0,ONE_ROW,&cRowsObtained,&rghRow),ExpectedHr);
|
|
|
|
//Check for the notifcation
|
|
if(m_fCommitPreserve)
|
|
TESTC(pCListener->GetTimesNotified() > 0) //notifcation should have succedded
|
|
else
|
|
TESTC(pCListener->GetTimesNotified() == 0) //rowset is zombied
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise the connection
|
|
if(pCListener && dwCookie)
|
|
pCListener->Unadvise(dwCookie);
|
|
|
|
//Release the rows
|
|
if(pIRowset && rghRow)
|
|
pIRowset->ReleaseRows(ONE_ROW,rghRow,NULL,NULL,NULL);
|
|
|
|
SAFE_RELEASE(pIRowset);
|
|
CleanUpTransaction(XACT_E_NOTRANSACTION); //No longer in a transaction
|
|
PROVIDER_FREE(rghRow);
|
|
SAFE_DELETE(pCListener); //CleanUpTransaction will call pCListener->Release
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCZombie::Terminate()
|
|
{
|
|
//FreeProperties
|
|
FreeProperties(&m_cPropSets,&m_rgPropSets);
|
|
|
|
return(TCTransaction::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCProperties)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCProperties - Test all of the Notifcation properties
|
|
//| Created: 08/05/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCProperties::Init()
|
|
{
|
|
return CTestNotify::Init();
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - DBPROP_IConnectionPointContainer
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCProperties::Variation_1()
|
|
{
|
|
TBEGIN
|
|
DBPROPFLAGS dwPropFlags;
|
|
CRowset RowsetA;
|
|
|
|
//Some provider might not support this property
|
|
TESTC_PROVIDER(SupportedProperty(DBPROP_IConnectionPointContainer, DBPROPSET_ROWSET))
|
|
|
|
//Get the PropInfo
|
|
dwPropFlags = GetPropInfoFlags(DBPROP_IConnectionPointContainer, DBPROPSET_ROWSET);
|
|
|
|
//Should be at least Read
|
|
TESTC(BITSET(dwPropFlags, DBPROPFLAGS_READ));
|
|
|
|
//Should be a ROWSET group
|
|
TESTC(BITSET(dwPropFlags,DBPROPFLAGS_ROWSET));
|
|
|
|
//Flags really shouldn't have any other values...
|
|
TESTC(BITCLEAR(dwPropFlags,~(DBPROPFLAGS_READ | DBPROPFLAGS_WRITE | DBPROPFLAGS_ROWSET)) );
|
|
|
|
//Get the PropValue
|
|
TESTC_(RowsetA.CreateRowset(USE_SUPPORTED_SELECT_ALLFROMTBL, IID_IConnectionPointContainer),S_OK);
|
|
TESTC(RowsetA.GetProperty(DBPROP_IConnectionPointContainer, DBPROPSET_ROWSET, VARIANT_TRUE));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - DBPROP_NOTIFICATIONPHASES
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCProperties::Variation_2()
|
|
{
|
|
TBEGIN
|
|
CRowset RowsetA;
|
|
|
|
ULONG_PTR ulValue;
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFICATIONPHASES, DBPROPSET_ROWSET, &ulValue))
|
|
|
|
//All Providers must support _FAILEDTODO / _DIDEVENT
|
|
TESTC(BITSET(ulValue, DBPROPVAL_NP_FAILEDTODO));
|
|
TESTC(BITSET(ulValue, DBPROPVAL_NP_DIDEVENT));
|
|
|
|
//Not all providers will supported all phases
|
|
TESTC_PROVIDER(BITSET(ulValue, DBPROPVAL_NP_OKTODO)==TRUE)
|
|
TESTC_PROVIDER(BITSET(ulValue, DBPROPVAL_NP_ABOUTTODO)==TRUE)
|
|
TESTC_PROVIDER(BITSET(ulValue, DBPROPVAL_NP_SYNCHAFTER)==TRUE)
|
|
|
|
//Make sure it has not other values besides the valid ones
|
|
TESTC(BITCLEAR(ulValue,~DBPROPVAL_NP_ALL));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - DBPROP_NOTIFIY [Reasons]
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCProperties::Variation_3()
|
|
{
|
|
TBEGIN
|
|
ULONG_PTR ulValue;
|
|
CRowset RowsetA;
|
|
|
|
//DBPROP_NOTIFYCOLUMNSET
|
|
ulValue = 0;
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYCOLUMNSET, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWDELETE
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWDELETE, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWFIRSTCHANGE
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWFIRSTCHANGE, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWINSERT
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWINSERT, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWRESYNCH
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWRESYNCH, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWSETRELEASE
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWSETRELEASE, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWUNDOCHANGE
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWUNDOCHANGE, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWUNDODELETE
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWUNDODELETE, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWUNDOINSERT
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWUNDOINSERT, DBPROPSET_ROWSET, &ulValue));
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
//DBPROP_NOTIFYROWUPDATE
|
|
ulValue = 0;
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_NOTIFYROWUPDATE, DBPROPSET_ROWSET, &ulValue))
|
|
TESTC(BITCLEAR(ulValue,~(DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER)));
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc Properties - DBPROP_REENTRANTEVENTS
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCProperties::Variation_4()
|
|
{
|
|
TBEGIN
|
|
VARIANT_BOOL bValue;
|
|
CRowset RowsetA;
|
|
|
|
//Not all providers will supports this property
|
|
TESTC_(RowsetA.CreateRowset(),S_OK);
|
|
TESTC_PROVIDER(RowsetA.GetProperty(DBPROP_REENTRANTEVENTS, DBPROPSET_ROWSET, &bValue))
|
|
TESTC(bValue == VARIANT_TRUE || bValue == VARIANT_FALSE);
|
|
|
|
CLEANUP:
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCProperties::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCNotifyCanceled)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCNotifyCanceled - Test CANCELED notifications
|
|
//| Created: 08/06/96
|
|
//| Updated: 12/01/96
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCNotifyCanceled::Init()
|
|
{
|
|
//this test case is specific for Rowset object and IRowsetNotify
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(IID_IRowsetNotify));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc CANCELED - IRowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyCanceled::Variation_1()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Create Rowset
|
|
CRowset Rowset;
|
|
Rowset.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_PROVIDER(Rowset.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Move the cursor from the first row. This way when RestartPosition is called it "forces"
|
|
//a FETCHPOSITIONCHANGE notification. Otherwise, if we don't move the NFP ways from the
|
|
//head of the rowset, the provider can optimize and not return FETCHPOSITIONCHANGE for no-op
|
|
//(no moving) senarios...
|
|
TESTC_(Rowset.GetNextRows(&hRow),S_OK);
|
|
TESTC_(Rowset.ReleaseRows(hRow),S_OK);
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, Rowset());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Need to turn on FETCHPOSITION
|
|
TESTC(pCListener->SetEvent(DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_ALL, ON));
|
|
|
|
//Try GetNextRows -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(Rowset.GetNextRows(&hRow), pCListener->IsCancelable(DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_OKTODO) ? DB_E_CANCELED : S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try RestartPosition -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(Rowset.RestartPosition(), pCListener->IsCancelable(DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_OKTODO) ? DB_E_CANCELED : S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc CANCELED - IRowsetChange
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyCanceled::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
HROW hNewRow = NULL;
|
|
HROW hRow = NULL;
|
|
DWORD dwCookie = 0;
|
|
DBROWSTATUS rgRowStatus[ONE_ROW];
|
|
CListener* pCListener = NULL;
|
|
|
|
//Create Rowset
|
|
CRowsetChange RowsetChange;
|
|
RowsetChange.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_PROVIDER(RowsetChange.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, RowsetChange());
|
|
pCListener->AddRef();
|
|
|
|
//Grab the row
|
|
TESTC_(RowsetChange.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Need to setup the SetData/InsertRow pData buffer
|
|
TESTC(RowsetChange.MakeRowData(&RowsetChange.m_pData));
|
|
|
|
//Try InsertRow -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_ROW_INSERT, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetChange.InsertRow(&hNewRow), pCListener->IsCancelable(DBREASON_ROW_INSERT, DBEVENTPHASE_OKTODO) ? DB_E_CANCELED : S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Need to setup the SetData/InsertRow pData buffer
|
|
TESTC(RowsetChange.MakeRowData(&RowsetChange.m_pData));
|
|
|
|
//Try SetData -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_COLUMN_SET, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetChange.ModifyRow(hRow), pCListener->IsCancelable(DBREASON_ROW_INSERT, DBEVENTPHASE_OKTODO) ? DB_E_CANCELED : S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try DeleteRow -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_ROW_DELETE, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetChange.DeleteRow(ONE_ROW,&hRow,rgRowStatus), pCListener->IsCancelable(DBREASON_ROW_INSERT, DBEVENTPHASE_OKTODO) ? DB_E_ERRORSOCCURRED : S_OK);
|
|
TESTC(rgRowStatus && pCListener->IsCancelable(DBREASON_ROW_INSERT, DBEVENTPHASE_OKTODO) ? rgRowStatus[0]==DBROWSTATUS_E_CANCELED : rgRowStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
RowsetChange.ReleaseRows(hNewRow);
|
|
RowsetChange.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc CANCELED - IRowsetUpdate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyCanceled::Variation_3()
|
|
{
|
|
TBEGIN
|
|
|
|
HROW hRow = NULL;
|
|
DWORD dwCookie = 0;
|
|
DBROWSTATUS* rgUndoneStatus = NULL;
|
|
DBROWSTATUS* rgUpdateStatus = NULL;
|
|
CListener* pCListener = NULL;
|
|
|
|
//Create Rowset
|
|
CRowsetUpdate RowsetUpdate;
|
|
RowsetUpdate.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_PROVIDER(RowsetUpdate.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, RowsetUpdate());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Grab the row
|
|
TESTC_(RowsetUpdate.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a few changes
|
|
TESTC_(RowsetUpdate.ModifyRow(hRow),S_OK);
|
|
|
|
//Try Undo -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_ROW_UNDOCHANGE, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetUpdate.UndoRow(ONE_ROW,&hRow,NULL,NULL,&rgUndoneStatus), pCListener->IsCancelable(DBREASON_ROW_UNDOCHANGE, DBEVENTPHASE_OKTODO) ? DB_E_ERRORSOCCURRED : S_OK);
|
|
TESTC(rgUndoneStatus && pCListener->IsCancelable(DBREASON_ROW_UNDOCHANGE, DBEVENTPHASE_OKTODO) ? rgUndoneStatus[0]==DBROWSTATUS_E_CANCELED : rgUndoneStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try Update -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_ROW_UPDATE, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetUpdate.UpdateRow(ONE_ROW,&hRow,NULL,NULL,&rgUpdateStatus),pCListener->IsCancelable(DBREASON_ROW_UPDATE, DBEVENTPHASE_OKTODO) ? DB_E_ERRORSOCCURRED : S_OK);
|
|
TESTC(rgUpdateStatus && pCListener->IsCancelable(DBREASON_ROW_UPDATE, DBEVENTPHASE_OKTODO) ? rgUpdateStatus[0]==DBROWSTATUS_E_CANCELED : rgUpdateStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
PROVIDER_FREE(rgUndoneStatus);
|
|
PROVIDER_FREE(rgUpdateStatus);
|
|
|
|
RowsetUpdate.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc CANCELED - IRowsetLocate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyCanceled::Variation_4()
|
|
{
|
|
// TO DO: Add your own code here
|
|
TOUTPUT(L"Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc CANCELED - IRowsetResynch
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyCanceled::Variation_5()
|
|
{
|
|
TBEGIN
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Create Rowset
|
|
CRowsetUpdate RowsetUpdate;
|
|
RowsetUpdate.SetProperty(DBPROP_CANHOLDROWS);
|
|
RowsetUpdate.SetProperty(DBPROP_IRowsetResynch);
|
|
TESTC_PROVIDER(RowsetUpdate.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK);
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, RowsetUpdate());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Grab the row
|
|
TESTC_(RowsetUpdate.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a few changes
|
|
TESTC_(RowsetUpdate.ModifyRow(hRow),S_OK);
|
|
|
|
//Try ResynchRows -> Cancel
|
|
TESTC(pCListener->SetCancel(DBREASON_ROW_RESYNCH, DBEVENTPHASE_OKTODO));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetUpdate.ResynchRows(ONE_ROW,&hRow,NULL,NULL,&rgRowStatus), pCListener->IsCancelable(DBREASON_ROW_RESYNCH, DBEVENTPHASE_OKTODO) ? DB_E_ERRORSOCCURRED : S_OK);
|
|
TESTC(rgRowStatus && pCListener->IsCancelable(DBREASON_ROW_RESYNCH, DBEVENTPHASE_OKTODO) ? rgRowStatus[0]==DBROWSTATUS_E_CANCELED : rgRowStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
|
|
SAFE_RELEASE(pCListener);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
|
|
RowsetUpdate.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc CANCELED - IRowsetScroll
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyCanceled::Variation_6()
|
|
{
|
|
// TO DO: Add your own code here
|
|
TOUTPUT(L"Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCNotifyCanceled::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return(CTestNotify::Terminate());
|
|
} // }}
|
|
// }}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TC_PROTOTYPE(TCNotifyFailure)
|
|
//*-----------------------------------------------------------------------
|
|
//| Test Case: TCNotifyFailure - Test E_FAIL from a listener
|
|
//| Created: 01/20/97
|
|
//*-----------------------------------------------------------------------
|
|
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Initialization Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCNotifyFailure::Init()
|
|
{
|
|
//this test case is specific for Rowset object and IRowsetNotify
|
|
TBEGIN;
|
|
TESTB = CTestNotify::Init();
|
|
if (TEST_PASS == TESTB)
|
|
TEST_PROVIDER(pCSource(0)->IsSupportedCP(IID_IRowsetNotify));
|
|
|
|
TRETURN
|
|
}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(1)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowset
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyFailure::Variation_1()
|
|
{
|
|
TBEGIN
|
|
HROW hRow = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Create Rowset
|
|
CRowset Rowset;
|
|
Rowset.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_PROVIDER(Rowset.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, Rowset());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Need to turn on FETCHPOSITION
|
|
TESTC(pCListener->SetEvent(DBREASON_ROWSET_FETCHPOSITIONCHANGE, DBEVENTPHASE_ALL, ON));
|
|
|
|
//Turn E_FAIL on for the listener
|
|
TESTC(pCListener->SetError(E_FAIL));
|
|
|
|
//Try GetNextRows -> E_FAIL
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(Rowset.GetNextRows(&hRow),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try RestartPosition -> E_FAIL
|
|
TESTC_(Rowset.ReleaseRows(hRow),S_OK);
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(Rowset.RestartPosition(),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(2)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetChange
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyFailure::Variation_2()
|
|
{
|
|
TBEGIN
|
|
|
|
HROW hNewRow = NULL;
|
|
HROW rghRows[TWO_ROWS] = {NULL,NULL};
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Create Rowset
|
|
CRowsetChange RowsetChange;
|
|
RowsetChange.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_PROVIDER(RowsetChange.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, RowsetChange());
|
|
pCListener->AddRef();
|
|
|
|
//Grab the row
|
|
TESTC_(RowsetChange.GetRow(FIRST_ROW, TWO_ROWS, rghRows),S_OK);
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Turn E_FAIL on for the listener
|
|
TESTC(pCListener->SetError(E_FAIL));
|
|
|
|
//Try InsertRow -> E_FAIL
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetChange.InsertRow(&hNewRow),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try SetData -> E_FAIL
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetChange.ModifyRow(rghRows[ROW_ONE]),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try DeleteRow -> E_FAIL
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetChange.DeleteRow(rghRows[ROW_TWO]),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
RowsetChange.ReleaseRows(hNewRow);
|
|
RowsetChange.ReleaseRows(TWO_ROWS, rghRows);
|
|
TableInsert(ONE_ROW); //Adjust the table
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(3)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetUpdate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyFailure::Variation_3()
|
|
{
|
|
TBEGIN
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS* rgUndoneStatus = NULL;
|
|
DBROWSTATUS* rgUpdateStatus = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Create Rowset
|
|
CRowsetUpdate RowsetUpdate;
|
|
RowsetUpdate.SetProperty(DBPROP_CANHOLDROWS);
|
|
TESTC_PROVIDER(RowsetUpdate.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK)
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, RowsetUpdate());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Grab the row
|
|
TESTC_(RowsetUpdate.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a few changes
|
|
TESTC_(RowsetUpdate.ModifyRow(hRow),S_OK);
|
|
|
|
//Turn E_FAIL on for the listener
|
|
TESTC(pCListener->SetError(E_FAIL));
|
|
|
|
//Try Undo -> E_FAIL
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetUpdate.UndoRow(hRow),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
//Try Update - should never be notified for Rows
|
|
//not actually needing updating on the backend (2.0 spec change)
|
|
TESTC(pCListener->SetError(S_OK));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetUpdate.UpdateRow(hRow),S_OK);
|
|
|
|
TESTC(pCListener->GetTimesNotified() == 0);
|
|
|
|
//Make another change
|
|
TESTC_(RowsetUpdate.ModifyRow(hRow),S_OK);
|
|
|
|
//Try Update - E_FAIL
|
|
TESTC(pCListener->SetError(E_FAIL));
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetUpdate.UpdateRow(hRow),S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
SAFE_RELEASE(pCListener);
|
|
PROVIDER_FREE(rgUndoneStatus);
|
|
PROVIDER_FREE(rgUpdateStatus);
|
|
|
|
RowsetUpdate.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(4)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetLocate
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyFailure::Variation_4()
|
|
{
|
|
// TO DO: Add your own code here
|
|
TOUTPUT(L"Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(5)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetResynch
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyFailure::Variation_5()
|
|
{
|
|
TBEGIN
|
|
|
|
HROW hRow = NULL;
|
|
DBROWSTATUS* rgRowStatus = NULL;
|
|
CListener* pCListener = NULL;
|
|
DWORD dwCookie = 0;
|
|
|
|
//Create Rowset
|
|
CRowsetUpdate RowsetUpdate;
|
|
RowsetUpdate.SetProperty(DBPROP_CANHOLDROWS);
|
|
RowsetUpdate.SetProperty(DBPROP_IRowsetResynch);
|
|
TESTC_PROVIDER(RowsetUpdate.CreateRowset(DBPROP_IConnectionPointContainer)==S_OK);
|
|
|
|
//Create Listener
|
|
pCListener = new CListener(IID_IRowsetNotify, RowsetUpdate());
|
|
pCListener->AddRef();
|
|
|
|
//Advise the connection,
|
|
TESTC_(pCListener->Advise(&dwCookie),S_OK);
|
|
|
|
//Grab the row
|
|
TESTC_(RowsetUpdate.GetRow(FIRST_ROW,&hRow),S_OK);
|
|
|
|
//Make a few changes
|
|
TESTC_(RowsetUpdate.ModifyRow(hRow),S_OK);
|
|
|
|
//Set E_FAIL on for the listener
|
|
TESTC(pCListener->SetError(E_FAIL));
|
|
|
|
//Try ResynchRows -> Cancel
|
|
TESTC(pCListener->ResetTimesNotified());
|
|
TESTC_(RowsetUpdate.ResynchRows(ONE_ROW,&hRow,NULL,NULL,&rgRowStatus),S_OK);
|
|
TESTC(rgRowStatus && rgRowStatus[0]==DBROWSTATUS_S_OK);
|
|
TESTC(pCListener->GetTimesNotified() > 0);
|
|
|
|
|
|
CLEANUP:
|
|
//Unadvise all connections
|
|
if(pCListener && dwCookie)
|
|
{
|
|
pCListener->Unadvise(dwCookie);
|
|
pCListener->ResetTimesNotified();
|
|
}
|
|
|
|
SAFE_RELEASE(pCListener);
|
|
PROVIDER_FREE(rgRowStatus);
|
|
|
|
RowsetUpdate.ReleaseRows(hRow);
|
|
TRETURN
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_VAR_PROTOTYPE(6)
|
|
//*-----------------------------------------------------------------------
|
|
// @mfunc E_FAIL - IRowsetScroll
|
|
//
|
|
// @rdesc TEST_PASS or TEST_FAIL
|
|
//
|
|
int TCNotifyFailure::Variation_6()
|
|
{
|
|
// TO DO: Add your own code here
|
|
TOUTPUT(L"Variation is not implemented");
|
|
return TEST_SKIPPED;
|
|
}
|
|
// }}
|
|
|
|
|
|
// {{ TCW_TERMINATE_METHOD
|
|
//--------------------------------------------------------------------
|
|
// @mfunc TestCase Termination Routine
|
|
//
|
|
// @rdesc TRUE or FALSE
|
|
//
|
|
BOOL TCNotifyFailure::Terminate()
|
|
{
|
|
// {{ TCW_TERM_BASECLASS_CHECK2
|
|
return CTestNotify::Terminate();
|
|
} // }}
|
|
// }}
|
|
// }}
|