home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / odbc / quiktest / custom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-21  |  14.6 KB  |  420 lines

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