1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
|
//*---------------------------------------------------------------------------------
//| Custom Auto Test DLL
//|
//| Title: CUSTOM.C
//|
//| Purpose:
//| This sample Auto Test DLL shows how an ODBC auto test may be written and
//| subsequently run via the ODBC Test application. To use this DLL:
//| 1) Compile the source code via the BUILD.EXE program
//| CUSTOM.C This shource file with test code
//| CUSTOM.H Include files with defines, macros, and prototypes
//| CUSTOM.RC Resource file for string tables
//| (Note that .H and .RC files are optional in for an Auto Test)
//| 2) Start the ODBC Test application
//| 3) If you have not done so, choose Tools, Manage Test Sources and define
//| a test source to run against
//| 4) Choose Tools, Manage Tests and add the CUSTOM.DLL created in step 1
//| to the list of installed test DLLs
//| 5) Choose Tools, Run Tests and select "Custom Auto Test" and your Test Source
//| from step #3
//| For more details, please see the SDK documentation.
//*---------------------------------------------------------------------------------
#include "autotest.h"
#include "custom.h"
//----------------------------------------------------------------------------------
// Defines and macros
//----------------------------------------------------------------------------------
typedef SWORD (FAR PASCAL *TESTCASEFUNC)(HENV FAR *, HDBC FAR *, HSTMT FAR *, lpSERVERINFO);
#define CHECKTEST(lps, exprc, actrc, func) \
{ \
if(!CheckTest(lps, exprc, actrc, (LPSTR)func)) \
return TEST_ABORTED; \
}
#define CHECKERRS(sErr) \
if(!sErr) szLogPrintf(lpSrvr, FALSE, "\t\tPassed\r\n\r\n"); \
else szLogPrintf(lpSrvr, FALSE, "\t\t%d errors\r\n\r\n", sErr);
//----------------------------------------------------------------------------------
// Local function prototypes
//----------------------------------------------------------------------------------
SWORD FAR PASCAL DoHelloWorld(HENV FAR * phenv, HDBC FAR * phdbc,
HSTMT FAR * phstmt, lpSERVERINFO lpSrvr);
SWORD FAR PASCAL DoDisplayInfoDesc(HENV FAR * phenv, HDBC FAR * phdbc,
HSTMT FAR * phstmt, lpSERVERINFO lpSrvr);
SWORD FAR PASCAL DoSimpleConnect(HENV FAR * phenv, HDBC FAR * phdbc,
HSTMT FAR * phstmt, lpSERVERINFO lpSrvr);
BOOL FAR PASCAL CheckTest(lpSERVERINFO lps, RETCODE exprc, RETCODE actrc,
LPSTR szFuncName);
//
// This structure is declared to describe the test cases and descriptions
// that this auto test supports. Note that the strings are stored in
// the resource fork, but could have been hard coded.
//
struct {
UINT uiName; // Test case name
UINT uiDesc; // Test case description
TESTCASEFUNC lpTestFunc; // Pointer to function to implement test
} TestCases[] = {
// szName szDesc lpTestFunc
// -------------------- ----------------------- ------------------------
idsHelloWorld, idsHelloWorldDesc, DoHelloWorld,
idsDisplayInfo, idsDisplayInfoDesc, DoDisplayInfoDesc,
idsSimpleConnect, idsSimpleConnectDesc, DoSimpleConnect,
};
//**************************************************************************
//*************************** External Interfaces ************************
//* These functions are called by ODBC Test to gather run-time information
//**************************************************************************
//*---------------------------------------------------------------------------------
//| AutoTestName:
//| This function is called to give the name of the auto test (which cannot
//| exceed AUTO_MAX_TEST_NAME) as well as the number of test cases which
//| are implemented in this test DLL.
//| Parms:
//| szName The name to be displayed
//| pcbTestCases Pointer to count of test cases
//| Returns:
//| TRUE if successful (pcbTestCases set), FALSE for error
//*---------------------------------------------------------------------------------
BOOL EXTFUN AutoTestName(LPSTR szName, UINT FAR * pcbTestCases)
{
strcpy( szName, "Custom Auto Test" );
*pcbTestCases = NumItems(TestCases);
return TRUE;
}
//*---------------------------------------------------------------------------------
//| AutoTestDesc:
//| This function is called by ODBC Test when a description of a specific
//| test case is required. The returned name must be no larger than
//| AUTO_MAX_TESTCASE_NAME including the NULL terminator. The returned
//| description must be no larger than AUTO_MAX_TESTDESC_NAME including the
//| NULL. iTest will be 1-based index of the test required.
//|
//| Note that iTest will start at 1 and will go to the number of
//| test cases as specified by the AutoTestName function.
//|
//| Parms:
//| iTest 1-based index of test case required
//| szName The name of the test case
//| szDesc A description of the test case
//| Returns:
//| TRUE if successful, FALSE for error
//*---------------------------------------------------------------------------------
BOOL EXTFUN AutoTestDesc(UWORD iTest, LPSTR szName, LPSTR szDesc)
{
// Extra protection should AutoTestName return invalid pcbTestCases
if(iTest > NumItems(TestCases))
return FALSE;
// Use GetRCString to retrieve resource string directly into return
// values
switch( iTest )
{
case 1:
strcpy( szName, "Hello World" );
strcpy( szDesc, "Uses szLogPrintf and szMessageBox" );
break;
case 2:
strcpy( szName, "Display SERVERINFO" );
strcpy( szDesc, "Writes the contents of SERVERINFO" );
break;
case 3:
strcpy( szName, "Simple Connect" );
strcpy( szDesc, "Do a connect using SERVERINFO" );
break;
}
return TRUE;
}
//*---------------------------------------------------------------------------------
//| AutoTestFunc:
//| This function is called to execute a test case selected by the user for
//| execution. The lpSrvr structure contains the information required for
//| connected (as defined in the chosen Test Source), as well as other
//| usefull information. See the AUTOTEST.H file for the structure
//| declaration.
//|
//| Use the GETBIT macro to determine which test should be executed.
//|
//| Parms:
//| lpSrvr Information required for running the test
//| Returns:
//| Nothing
//*---------------------------------------------------------------------------------
void EXTFUN AutoTestFunc(lpSERVERINFO lpSrvr)
{
HENV henv=NULL;
HDBC hdbc=NULL;
HSTMT hstmt0=NULL;
int iDex;
SWORD cErrCnt; // Count errors
char szName[AUTO_MAX_TESTCASE_NAME+6]; // Room for NULL and \r\n
// Sets the error count to 0
InitTest(lpSrvr);
// Loop through the count of test cases looking for set bits via GETBIT.
// When a bit is set, that test is to be run. We've stored the
// function address which will implement the test, so simply call it.
for(iDex=1; iDex<=NumItems(TestCases); iDex++)
if(GETBIT(lpSrvr->rglMask, iDex)) {
// Print out title of test
switch( iDex )
{
case 1:
strcpy( szName, "Hello World" );
break;
case 2:
strcpy( szName, "Display SERVERINFO" );
break;
case 3:
strcpy( szName, "Simple Connect" );
break;
}
szLogPrintf(lpSrvr, FALSE, "%s:\r\n", (LPSTR)szName);
// Call the test case and add errors
cErrCnt =
(*TestCases[(iDex-1)].lpTestFunc)(&henv, &hdbc, &hstmt0, lpSrvr);
if(cErrCnt != TEST_ABORTED)
lpSrvr->cErrors += cErrCnt;
else
goto abort;
}
return;
// When a test must abort, the test case should call the AbortTest
// macro which sets lpSrvr->cErrors to TEST_ABORTED.
abort:
return;
}
//**************************************************************************
//***************************** Test Cases *******************************
//* The following functions implement the tests
//**************************************************************************
//*---------------------------------------------------------------------------------
//| DoHelloWord:
//| This is a simple test which uses the szLogPrintf and szMessageBox
//| functions defined in GATORTST.DLL.
//|
//| Note that this test also simulates an error by returning a count
//| of 1. This value is then totaled by ODBC Test and displayed as
//| part of the grand total.
//|
//| Returns:
//| Number of Errors or TEST_ABORTED
//*---------------------------------------------------------------------------------
SWORD FAR PASCAL DoHelloWorld(HENV FAR * phenv, HDBC FAR * phdbc,
HSTMT FAR * phstmt, lpSERVERINFO lpSrvr)
{
SWORD sErr=1; // Pretend there was 1 error
// The szMessageBox function will display a formatted message via the
// Windows MessageBox function. This function should not be used
// for standard testing since a good test will run unattended.
szMessageBox(lpSrvr->hwnd,
MB_ICONINFORMATION | MB_OK,
"Hello World",
"This is a sample message.");
// The szLogPrintf function is preferred for output operations. It will
// format your string using wvsprintf (which has a limit of 2000 characters)
// and log the result both to the output window and to a file per
// user instructions.
szLogPrintf(lpSrvr, FALSE, "\tHello World!!\r\n");
// check for errors
CHECKERRS(sErr);
return sErr;
}
//*---------------------------------------------------------------------------------
//| DoDisplayInfoDesc:
//| This test case will use the szLogPrintf function to dump the contents
//| of the lpSrvr structure.
//|
//| Returns:
//| Number of Errors or TEST_ABORTED
//*---------------------------------------------------------------------------------
SWORD FAR PASCAL DoDisplayInfoDesc(HENV FAR * phenv, HDBC FAR * phdbc,
HSTMT FAR * phstmt, lpSERVERINFO lpSrvr)
{
SWORD sErr=0;
#ifndef WIN32
#define szAddress "%04X:%04X\r\n"
#else
#define szAddress "%08X\r\n"
#endif
// The hwnd parameter is the window of style "edit" which is used for output.
// The szLogFile parameter is used for file logging of output.
szLogPrintf(lpSrvr, FALSE,
"\thwnd:\t\t\t\t\t\t\t%04X\r\n", lpSrvr->hwnd);
szLogPrintf(lpSrvr, FALSE,
"\tszLogFile:\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szLogFile);
// Print out address information. Note that szAddress is conditionaly compiled
// to handle 16 and 32-bit. It will be concatenated to the format string
// by the compiler to create a file platform correct string.
szLogPrintf(lpSrvr, FALSE,
"\thenv:\t\t\t\t\t\t\t" szAddress,
lpSrvr->henv);
szLogPrintf(lpSrvr, FALSE,
"\thdbc:\t\t\t\t\t\t\t" szAddress,
lpSrvr->hdbc);
szLogPrintf(lpSrvr, FALSE,
"\thstmt:\t\t\t\t\t\t\t" szAddress,
lpSrvr->hstmt);
// The following are defined via the Tools, Manage Test Sources dialog in
// the ODBC Test application.
szLogPrintf(lpSrvr, FALSE,
"\tszSource:\t\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szSource);
szLogPrintf(lpSrvr, FALSE,
"\tszValidServer0:\t\t\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szValidServer0);
szLogPrintf(lpSrvr, FALSE,
"\tszValidLogin0:\t\t\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szValidLogin0);
szLogPrintf(lpSrvr, FALSE,
"\tszValidPassword0:\t\t\t%s\r\n", (LPSTR)lpSrvr->szValidPassword0);
szLogPrintf(lpSrvr, FALSE,
"\tszKeywords:\t\t\t%s\r\n", (LPSTR)lpSrvr->szKeywords);
// The following elements describe the run-time environment
szLogPrintf(lpSrvr, FALSE,
"\tcErrors:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->cErrors);
szLogPrintf(lpSrvr, FALSE,
"\tfDebug:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fDebug);
szLogPrintf(lpSrvr, FALSE,
"\tfScreen:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fScreen);
szLogPrintf(lpSrvr, FALSE,
"\tfLog:\t\t\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fLog);
szLogPrintf(lpSrvr, FALSE,
"\tfIsolate:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fIsolate);
szLogPrintf(lpSrvr, FALSE,
"\tvCursorLib:\t\t\t\t%lu\r\n", (LPSTR)lpSrvr->vCursorLib);
szLogPrintf(lpSrvr, FALSE,
"\thLoadedInst:\t\t\t%04X\r\n", (LPSTR)lpSrvr->hLoadedInst);
// check for errors
CHECKERRS(sErr);
return sErr;
}
//*---------------------------------------------------------------------------------
//| DoSimpleConnect:
//| This test case will use the information in SERVERINFO to make a connection
//| to the chosen test source.
//|
//| Returns:
//| Number of Errors or TEST_ABORTED
//*---------------------------------------------------------------------------------
SWORD FAR PASCAL DoSimpleConnect(HENV FAR * phenv, HDBC FAR * phdbc,
HSTMT FAR * phstmt, lpSERVERINFO lpSrvr)
{
RETCODE rc;
SWORD sErr=0;
// This test will assume that the ODBC handles passed in
// are NULL. One could have this function do a connection
// and pass the handles to other test functions.
rc = SQLAllocEnv(phenv);
CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLAllocEnv");
rc = SQLAllocConnect(*phenv, phdbc);
CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLAllocConnect");
rc = SQLConnect(*phdbc, lpSrvr->szValidServer0, SQL_NTS,
lpSrvr->szValidLogin0, SQL_NTS,
lpSrvr->szValidPassword0, SQL_NTS);
CHECKTEST(lpSrvr,
(RETCODE)((rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
? rc : SQL_SUCCESS),
rc, "SQLConnect");
rc = SQLAllocStmt(*phdbc, phstmt);
CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLAllocStmt");
rc = SQLFreeStmt(*phstmt, SQL_DROP);
CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLFreeStmt");
rc = SQLDisconnect(*phdbc);
CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLDisconnect");
rc = SQLFreeConnect(*phdbc);
CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLFreeConnect");
rc = SQLFreeEnv(*phenv);
CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLFreeEnv");
// check for errors
CHECKERRS(sErr);
return sErr;
}
//**************************************************************************
//************************* Utility Functions ****************************
//* This section contains internal utility functions
//**************************************************************************
//*---------------------------------------------------------------------------------
//| CheckTest:
//| This function will do a simple comparison of return codes and issue
//| erros on failure. Use the CHECKTEST macro to invoke.
//|
//| Returns:
//| TRUE if the codes match, FALSE on error
//*---------------------------------------------------------------------------------
BOOL FAR PASCAL CheckTest(lpSERVERINFO lps, RETCODE exprc, RETCODE actrc,
LPSTR szFuncName)
{
if(exprc != actrc) {
szLogPrintf(lps, FALSE, "\t%s failed:\r\n", (LPSTR)szFuncName);
szLogPrintf(lps, FALSE, "\t\tExpected: %d\r\n", exprc);
szLogPrintf(lps, FALSE, "\t\tActual: %d\r\n", actrc);
return FALSE;
}
else
return TRUE;
}
|