LCOV - code coverage report
Current view: top level - src/ctlib/unittests - errors.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 336 363 92.6 %
Date: 2026-11-07 23:58:45 Functions: 21 21 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Try usage of callbacks to get errors and messages from library.
       3             :  */
       4             : #include "common.h"
       5             : 
       6             : #include <bkpublic.h>
       7             : 
       8             : #define ALL_TESTS \
       9             :         TEST(ct_callback) \
      10             :         TEST(ct_res_info) \
      11             :         TEST(ct_results) \
      12             :         TEST(ct_cancel) \
      13             :         TEST(ct_send) \
      14             :         TEST(cs_config) \
      15             :         TEST(blk_init) \
      16             :         TEST(cs_loc_alloc) \
      17             :         TEST(cs_loc_drop) \
      18             :         TEST(cs_locale) \
      19             :         TEST(ct_dynamic) \
      20             :         TEST(ct_connect) \
      21             :         TEST(ct_command) \
      22             :         TEST(ct_cursor) \
      23             :         TEST(ct_con_props) \
      24             :         TEST(ct_cmd_props) \
      25             :         TEST(cs_convert) \
      26             :         TEST(cs_dt_info)
      27             : 
      28             : /* forward declare all tests */
      29             : #undef TEST
      30             : #define TEST(name) static void test_ ## name(void);
      31             : ALL_TESTS
      32             : 
      33             : static CS_CONTEXT *ctx;
      34             : static CS_CONNECTION *conn;
      35             : static CS_COMMAND *cmd;
      36             : 
      37          10 : TEST_MAIN()
      38             : {
      39          10 :         bool verbose = true;
      40             : 
      41          10 :         printf("%s: Testing message callbacks\n", __FILE__);
      42             :         if (verbose) {
      43          10 :                 printf("Trying login\n");
      44             :         }
      45          10 :         check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
      46             : 
      47          10 :         check_call(cs_config, (ctx, CS_SET, CS_MESSAGE_CB, (CS_VOID*) cslibmsg_cb, CS_UNUSED, NULL));
      48             : 
      49             :         /* set different callback for the connection */
      50          10 :         check_call(ct_callback, (NULL, conn, CS_SET, CS_CLIENTMSG_CB, (CS_VOID*) clientmsg_cb2));
      51             : 
      52             :         /* call all tests */
      53             : #undef TEST
      54             : #define TEST(name) test_ ## name();
      55          10 :         ALL_TESTS
      56             : 
      57             :         if (verbose) {
      58          10 :                 printf("Trying logout\n");
      59             :         }
      60          10 :         check_call(try_ctlogout, (ctx, conn, cmd, verbose));
      61             : 
      62             :         if (verbose) {
      63          10 :                 printf("Test succeeded\n");
      64             :         }
      65          10 :         return 0;
      66             : }
      67             : 
      68             : static void
      69          10 : test_ct_callback(void)
      70             : {
      71             :         void *ptr;
      72             : 
      73             :         /* this should fail, context or connection should be not NULL */
      74          10 :         check_fail(ct_callback, (NULL, NULL, CS_SET, CS_SERVERMSG_CB, servermsg_cb));
      75          10 :         check_last_message(CTMSG_NONE, 0, NULL);
      76             : 
      77             :         /* this should fail, context and connection cannot be both not NULL */
      78          10 :         check_fail(ct_callback, (ctx, conn, CS_SET, CS_SERVERMSG_CB, servermsg_cb));
      79          10 :         check_last_message(CTMSG_CLIENT2, 0x01010133, NULL);
      80             : 
      81             :         /* this should fail, invalid action */
      82          10 :         check_fail(ct_callback, (ctx, NULL, 3, CS_SERVERMSG_CB, servermsg_cb));
      83          10 :         check_last_message(CTMSG_CLIENT, 0x01010105, "action");
      84             : 
      85             :         /* this should fail, invalid action */
      86          10 :         check_fail(ct_callback, (NULL, conn, 3, CS_SERVERMSG_CB, servermsg_cb));
      87          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, "action");
      88             : 
      89             :         /* this should fail, invalid type */
      90          10 :         check_fail(ct_callback, (ctx, NULL, CS_SET, 20, servermsg_cb));
      91          10 :         check_last_message(CTMSG_CLIENT, 0x01010105, "type");
      92             : 
      93             :         /* this should fail, invalid type */
      94          10 :         check_fail(ct_callback, (NULL, conn, CS_SET, 20, servermsg_cb));
      95          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, "type");
      96             : 
      97             :         /* NULL func getting it */
      98          10 :         check_fail(ct_callback, (NULL, conn, CS_GET, CS_CLIENTMSG_CB, NULL));
      99          10 :         check_last_message(CTMSG_CLIENT2, 0x01010103, "The parameter func cannot be NULL");
     100             : 
     101          10 :         check_fail(ct_callback, (NULL, conn, CS_GET, CS_SERVERMSG_CB, NULL));
     102          10 :         check_last_message(CTMSG_CLIENT2, 0x01010103, "The parameter func cannot be NULL");
     103             : 
     104             :         /* invalid type with action CS_GET */
     105          10 :         check_fail(ct_callback, (NULL, conn, CS_GET, 20, NULL));
     106          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, "An illegal value of 20 given for parameter type");
     107             : 
     108          10 :         ptr = (char*)0 + 123;
     109          10 :         check_fail(ct_callback, (NULL, conn, CS_GET, 20, &ptr));
     110          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, "An illegal value of 20 given for parameter type");
     111          10 :         if (ptr != (char*)0 + 123) {
     112           0 :                 fprintf(stderr, "Invalid pointer %p\n", ptr);
     113           0 :                 exit(1);
     114             :         }
     115          10 : }
     116             : 
     117             : static void
     118          10 : test_ct_res_info(void)
     119             : {
     120             :         CS_RETCODE ret;
     121             :         CS_INT result_type;
     122             :         CS_INT num_cols;
     123             :         CS_INT count;
     124             : 
     125          10 :         check_call(ct_command, (cmd, CS_LANG_CMD, "SELECT 'hi' AS greeting", CS_NULLTERM, CS_UNUSED));
     126          10 :         check_call(ct_send, (cmd));
     127             : 
     128          10 :         while ((ret = ct_results(cmd, &result_type)) == CS_SUCCEED) {
     129          20 :                 switch (result_type) {
     130             :                 case CS_CMD_SUCCEED:
     131             :                 case CS_CMD_DONE:
     132             :                         break;
     133          10 :                 case CS_ROW_RESULT:
     134             :                         /* this should fail, invalid number */
     135          10 :                         check_fail(ct_res_info, (cmd, 1234, &num_cols, CS_UNUSED, NULL));
     136          10 :                         check_last_message(CTMSG_CLIENT2, 0x01010105, "operation");
     137             : 
     138          30 :                         while ((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
     139          10 :                                 continue;
     140             : 
     141          10 :                         if (ret != CS_END_DATA) {
     142           0 :                                 fprintf(stderr, "ct_fetch() unexpected return %d.\n", (int) ret);
     143           0 :                                 exit(1);
     144             :                         }
     145             :                         break;
     146           0 :                 default:
     147           0 :                         fprintf(stderr, "ct_results() unexpected result_type %d.\n", (int) result_type);
     148           0 :                         exit(1);
     149             :                 }
     150             :         }
     151          10 :         if (ret != CS_END_RESULTS) {
     152           0 :                 fprintf(stderr, "ct_results() unexpected return %d.\n", (int) ret);
     153           0 :                 exit(1);
     154             :         }
     155          10 : }
     156             : 
     157             : static void
     158          90 : check_results(CS_INT expected_type)
     159             : {
     160             :         CS_INT result_type;
     161             : 
     162          90 :         check_call(ct_results, (cmd, &result_type));
     163          90 :         if (result_type != expected_type) {
     164           0 :                 fprintf(stderr, "ct_results() unexpected result_type %d, expected %d.\n", (int) result_type, (int) expected_type);
     165           0 :                 exit(1);
     166             :         }
     167          90 : }
     168             : 
     169             : static void
     170          70 : check_fetch(CS_RETCODE expected_ret)
     171             : {
     172             :         CS_RETCODE ret;
     173             :         CS_INT count;
     174             : 
     175          70 :         ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count);
     176          70 :         if (ret != expected_ret) {
     177           0 :                 fprintf(stderr, "ct_fetch() unexpected return %d, expected %d.\n", (int) ret, (int) expected_ret);
     178           0 :                 exit(1);
     179             :         }
     180          70 : }
     181             : 
     182             : static void
     183          10 : test_ct_results(void)
     184             : {
     185             :         CS_RETCODE ret;
     186             :         CS_INT result_type;
     187             : 
     188          10 :         check_call(ct_command, (cmd, CS_LANG_CMD, "SELECT 1 UNION ALL SELECT 2 SELECT 3 WHERE 1 = 0 SELECT 4",
     189             :                                 CS_NULLTERM, CS_UNUSED));
     190          10 :         check_call(ct_send, (cmd));
     191             : 
     192          10 :         check_results(CS_ROW_RESULT);
     193             : 
     194             :         /* this should fail, rows are not fetched */
     195          10 :         check_fail(ct_results, (cmd, &result_type));
     196          10 :         check_last_message(CTMSG_CLIENT2, 0x010101a3, "fetchable results");
     197             : 
     198             :         /* this should fail, not all rows are fetched */
     199          10 :         check_fetch(CS_SUCCEED);
     200          10 :         check_fail(ct_results, (cmd, &result_type));
     201          10 :         check_last_message(CTMSG_CLIENT2, 0x010101a3, "fetchable results");
     202             : 
     203          10 :         check_fetch(CS_SUCCEED);
     204          10 :         check_fetch(CS_END_DATA);
     205          10 :         check_results(CS_CMD_DONE);
     206             : 
     207             :         /* empty result set, no rows to fetch */
     208          10 :         check_results(CS_ROW_RESULT);
     209          10 :         check_results(CS_CMD_DONE);
     210             : 
     211          10 :         check_results(CS_ROW_RESULT);
     212          10 :         check_fetch(CS_SUCCEED);
     213          10 :         check_fetch(CS_END_DATA);
     214          10 :         check_results(CS_CMD_DONE);
     215             : 
     216          10 :         ret = ct_results(cmd, &result_type);
     217          10 :         if (ret != CS_END_RESULTS) {
     218           0 :                 fprintf(stderr, "ct_results() unexpected return %d.\n", (int) ret);
     219           0 :                 exit(1);
     220             :         }
     221          10 : }
     222             : 
     223             : static void
     224          10 : test_ct_cancel(void)
     225             : {
     226             :         CS_RETCODE ret;
     227             :         CS_INT result_type;
     228             : 
     229          10 :         check_call(ct_command, (cmd, CS_LANG_CMD, "SELECT 1 UNION ALL SELECT 2", CS_NULLTERM, CS_UNUSED));
     230          10 :         check_call(ct_send, (cmd));
     231          10 :         check_results(CS_ROW_RESULT);
     232             : 
     233          10 :         check_call(ct_cancel, (NULL, cmd, CS_CANCEL_ALL));
     234             : 
     235             :         /* this should fail, command is idle after a cancel */
     236          10 :         check_fail(ct_fetch, (cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, NULL));
     237          10 :         check_last_message(CTMSG_CLIENT2, 0x0101019b, "idle");
     238             : 
     239             :         /* a new command can be sent after a cancel */
     240          10 :         check_call(ct_command, (cmd, CS_LANG_CMD, "SELECT 3", CS_NULLTERM, CS_UNUSED));
     241          10 :         check_call(ct_send, (cmd));
     242          10 :         check_results(CS_ROW_RESULT);
     243          10 :         check_fetch(CS_SUCCEED);
     244          10 :         check_fetch(CS_END_DATA);
     245          10 :         check_results(CS_CMD_DONE);
     246             : 
     247          10 :         ret = ct_results(cmd, &result_type);
     248          10 :         if (ret != CS_END_RESULTS) {
     249           0 :                 fprintf(stderr, "ct_results() unexpected return %d.\n", (int) ret);
     250           0 :                 exit(1);
     251             :         }
     252          10 : }
     253             : 
     254             : static void
     255          10 : test_ct_send(void)
     256             : {
     257             :         /* reset command to idle state */
     258          10 :         check_call(ct_cmd_drop, (cmd));
     259          10 :         check_call(ct_cmd_alloc, (conn, &cmd));
     260             : 
     261             :         /* this should fail, invalid command state */
     262          10 :         check_fail(ct_send, (cmd));
     263          10 :         check_last_message(CTMSG_CLIENT2, 0x0101019b, "idle");
     264          10 : }
     265             : 
     266             : static void
     267          10 : test_cs_config(void)
     268             : {
     269             :         /* a set of invalid, not accepted values */
     270             :         static const CS_INT invalid_values[] = {
     271             :                 -1,
     272             :                 -5,
     273             :                 -200,
     274             :                 CS_WILDCARD,
     275             :                 CS_NO_LIMIT,
     276             :                 CS_UNUSED,
     277             :                 0 /* terminator */
     278             :         };
     279             :         const CS_INT *p_invalid;
     280             :         CS_INT out_len;
     281             :         char out_buf[8];
     282             : 
     283          10 :         check_call(cs_config, (ctx, CS_SET, CS_USERDATA, (CS_VOID *)"test",  CS_NULLTERM, NULL));
     284             : 
     285             :         /* check that value written does not have the NUL terminator */
     286          10 :         strcpy(out_buf, "123456");
     287          10 :         check_call(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 8, NULL));
     288          10 :         if (strcmp(out_buf, "test56") != 0) {
     289           0 :                 fprintf(stderr, "Wrong output buffer '%s'\n", out_buf);
     290           0 :                 exit(1);
     291             :         }
     292             : 
     293          10 :         check_call(cs_config, (ctx, CS_SET, CS_USERDATA, (CS_VOID *)"test123",  4, NULL));
     294             : 
     295             :         /* check that value written does not have more characters */
     296          10 :         strcpy(out_buf, "123456");
     297          10 :         check_call(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 8, NULL));
     298          10 :         if (strcmp(out_buf, "test56") != 0) {
     299           0 :                 fprintf(stderr, "Wrong output buffer '%s'\n", out_buf);
     300           0 :                 exit(1);
     301             :         }
     302             : 
     303          60 :         for (p_invalid = invalid_values; *p_invalid != 0; ++p_invalid) {
     304          60 :                 check_fail(cs_config, (ctx, CS_SET, CS_USERDATA, (CS_VOID *)"test", *p_invalid, NULL));
     305          60 :                 check_last_message(CTMSG_CSLIB, 0x02010106, "buflen");
     306             :         }
     307             : 
     308             :         /* wrong action */
     309          10 :         check_fail(cs_config, (ctx, 1000, CS_USERDATA, (CS_VOID *)"test", 4, NULL));
     310          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, "action");
     311             : 
     312             :         /* wrong property */
     313          10 :         check_fail(cs_config, (ctx, CS_SET, 100000, NULL, CS_UNUSED, NULL));
     314          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, "property");
     315             : 
     316             :         /* read exactly expected bytes */
     317          10 :         check_call(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 4, NULL));
     318             : 
     319             :         /* wrong buflen getting value */
     320          10 :         out_len = -123;
     321          10 :         check_fail(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, CS_NULLTERM, &out_len));
     322          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, "buflen");
     323          10 :         if (out_len != -123) {
     324           0 :                 fprintf(stderr, "Wrong buffer length returned\n");
     325           0 :                 exit(1);
     326             :         }
     327             : 
     328             :         /* shorter buffer */
     329          10 :         out_len = -123;
     330          10 :         strcpy(out_buf, "123456");
     331          10 :         check_fail(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 2, &out_len));
     332          10 :         check_last_message(CTMSG_CSLIB, 0x02010102, " 2 bytes");
     333          10 :         if (out_len != 4) {
     334           0 :                 fprintf(stderr, "Wrong buffer length returned\n");
     335           0 :                 exit(1);
     336             :         }
     337          10 :         if (strcmp(out_buf, "123456") != 0) {
     338           0 :                 fprintf(stderr, "Wrong buffer returned\n");
     339           0 :                 exit(1);
     340             :         }
     341          10 : }
     342             : 
     343             : static void
     344          10 : test_blk_init(void)
     345             : {
     346             :         CS_BLKDESC *blkdesc;
     347          10 :         check_call(blk_alloc, (conn, BLK_VERSION_100, &blkdesc));
     348             : 
     349             :         /* invalid direction */
     350          10 :         check_fail(blk_init, (blkdesc, 100, "testname", CS_NULLTERM));
     351          10 :         check_last_message(CTMSG_CLIENT2, 0x0101010f, "CS_BLK_IN or CS_BLK_OUT");
     352             : 
     353             :         /* invalid tablename */
     354          10 :         check_fail(blk_init, (blkdesc, CS_BLK_IN, NULL, CS_NULLTERM));
     355          10 :         check_last_message(CTMSG_CLIENT2, 0x01010106, "tblname cannot be NULL");
     356             : 
     357             :         /* invalid tablename length */
     358          10 :         check_fail(blk_init, (blkdesc, CS_BLK_IN, "testname", -4));
     359          10 :         check_last_message(CTMSG_CLIENT2, 0x01010104, "tblnamelen has an illegal value of -4");
     360             : 
     361          10 :         check_call(blk_drop, (blkdesc));
     362          10 : }
     363             : 
     364             : static void
     365          10 : test_cs_loc_alloc(void)
     366             : {
     367             :         /* no context or locale */
     368          10 :         check_fail(cs_loc_alloc, (NULL, NULL));
     369          10 :         check_last_message(CTMSG_NONE, 0, NULL);
     370             : 
     371             :         /* no locale */
     372          10 :         check_fail(cs_loc_alloc, (ctx, NULL));
     373          10 :         check_last_message(CTMSG_CSLIB, 0x02010104, " loc_pointer cannot be NULL");
     374          10 : }
     375             : 
     376             : static void
     377          10 : test_cs_loc_drop(void)
     378             : {
     379             :         /* no context or locale */
     380          10 :         check_fail(cs_loc_drop, (NULL, NULL));
     381          10 :         check_last_message(CTMSG_NONE, 0, NULL);
     382             : 
     383             :         /* no locale */
     384          10 :         check_fail(cs_loc_drop, (ctx, NULL));
     385          10 :         check_last_message(CTMSG_CSLIB, 0x02010104, " locale cannot be NULL");
     386          10 : }
     387             : 
     388             : static void
     389          10 : test_cs_locale(void)
     390             : {
     391             :         CS_LOCALE *locale;
     392             : 
     393          10 :         check_call(cs_loc_alloc, (ctx, &locale));
     394             : 
     395          10 :         check_call(cs_locale, (ctx, CS_SET, locale, CS_SYB_CHARSET, "utf8", 4, NULL));
     396             : 
     397             :         /* no context  */
     398          10 :         check_fail(cs_locale, (NULL, CS_SET, locale, CS_SYB_CHARSET, "utf8", 4, NULL));
     399          10 :         check_last_message(CTMSG_NONE, 0, NULL);
     400             : 
     401             :         /* no locale  */
     402          10 :         check_fail(cs_locale, (ctx, CS_SET, NULL, CS_SYB_CHARSET, "utf8", 4, NULL));
     403          10 :         check_last_message(CTMSG_CSLIB, 0x02010104, " locale cannot be NULL");
     404             : 
     405             :         /* wrong action */
     406          10 :         check_fail(cs_locale, (ctx, 1000, locale, CS_SYB_CHARSET, "utf8", 4, NULL));
     407          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " 1000 was given for parameter action");
     408             : 
     409             :         /* wrong type */
     410          10 :         check_fail(cs_locale, (ctx, CS_SET, locale, 1000, "utf8", 4, NULL));
     411          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " 1000 was given for parameter type");
     412             : 
     413             :         /* wrong length  */
     414          10 :         check_fail(cs_locale, (ctx, CS_SET, locale, CS_SYB_CHARSET, "utf8", -4, NULL));
     415          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " -4 was given for parameter buflen");
     416             : 
     417          10 :         check_call(cs_loc_drop, (ctx, locale));
     418          10 : }
     419             : 
     420             : static void
     421          10 : test_ct_dynamic(void)
     422             : {
     423             :         /* wrong type */
     424          10 :         check_fail(ct_dynamic, (cmd, 10000, "test", CS_NULLTERM, "query", CS_NULLTERM));
     425          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " 10000 given for parameter type");
     426             : 
     427             :         /* wrong id length */
     428          10 :         check_fail(ct_dynamic, (cmd, CS_PREPARE, "test", -5, "query", CS_NULLTERM));
     429          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -5 given for parameter idlen");
     430             : 
     431             :         /* wrong query length */
     432          10 :         check_fail(ct_dynamic, (cmd, CS_PREPARE, "test", CS_NULLTERM, "query", -6));
     433          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -6 given for parameter buflen");
     434             : 
     435             :         /* wrong id and query length */
     436          10 :         check_fail(ct_dynamic, (cmd, CS_PREPARE, "test", -5, "query", -6));
     437          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -5 given for parameter idlen");
     438             : 
     439             :         /* id not existing */
     440          10 :         check_fail(ct_dynamic, (cmd, CS_DEALLOC, "notexisting", CS_NULLTERM, NULL, CS_UNUSED));
     441          10 :         check_last_message(CTMSG_CLIENT2, 0x01010187, " specified id does not exist ");
     442             : 
     443             :         /* wrong id length */
     444          10 :         check_fail(ct_dynamic, (cmd, CS_DEALLOC, "notexisting", -7, NULL, CS_UNUSED));
     445          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -7 given for parameter idlen");
     446          10 : }
     447             : 
     448             : static void
     449          10 : test_ct_connect(void)
     450             : {
     451             :         CS_CONNECTION *conn;
     452             : 
     453          10 :         check_call(ct_con_alloc, (ctx, &conn));
     454             : 
     455             :         /* wrong server name length */
     456          10 :         check_fail(ct_connect, (conn, "test", -5));
     457          10 :         check_last_message(CTMSG_CLIENT, 0x01010105, " -5 given for parameter snamelen");
     458             : 
     459          10 :         check_call(ct_con_drop, (conn));
     460          10 : }
     461             : 
     462             : static void
     463          10 : test_ct_command(void)
     464             : {
     465             :         /* wrong query length, CS_UNUSED, this was behaving differently */
     466          10 :         check_fail(ct_command, (cmd, CS_LANG_CMD, "test", CS_UNUSED, CS_UNUSED));
     467          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " given for parameter buflen");
     468             : 
     469             :         /* wrong query length */
     470          10 :         check_fail(ct_command, (cmd, CS_LANG_CMD, "test", -7, CS_UNUSED));
     471          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -7 given for parameter buflen");
     472             : 
     473             :         /* wrong query length, RPC */
     474          10 :         check_fail(ct_command, (cmd, CS_RPC_CMD, "test", -3, CS_UNUSED));
     475          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -3 given for parameter buflen");
     476          10 : }
     477             : 
     478             : static void
     479          10 : test_ct_cursor(void)
     480             : {
     481             :         /* wrong name length */
     482          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DECLARE, "test", -4, "query", CS_NULLTERM, CS_UNUSED));
     483          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -4 given for parameter namelen");
     484             : 
     485             :         /* wrong query length */
     486          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DECLARE, "test", CS_NULLTERM, "query", -3, CS_UNUSED));
     487          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -3 given for parameter tlen");
     488             : 
     489             :         /* wrong name and query length */
     490          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DECLARE, "test", -11, "query", -3, CS_UNUSED));
     491          10 :         check_last_message(CTMSG_CLIENT2, 0x01010105, " -11 given for parameter namelen");
     492             : 
     493             :         /* name present without cursor, priority to name */
     494          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_ROWS, "name", CS_NULLTERM, NULL, CS_UNUSED, (CS_INT) 1));
     495          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The name parameter must be NULL");
     496             : 
     497             :         /* no cursor */
     498          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_ROWS, NULL, CS_UNUSED, NULL, CS_UNUSED, (CS_INT) 1));
     499          10 :         check_last_message(CTMSG_CLIENT2, 0x01010112, "A cursor must be declared before this command type can be initialized");
     500             : 
     501          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_CLOSE, NULL, CS_UNUSED, NULL, CS_UNUSED, CS_DEALLOC));
     502          10 :         check_last_message(CTMSG_CLIENT2, 0x010101ab, "A cursor must be opened before this command type can be initialized.");
     503             : 
     504          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DEALLOC, NULL, CS_UNUSED, NULL, CS_UNUSED, CS_UNUSED));
     505          10 :         check_last_message(CTMSG_CLIENT2, 0x01010112, "A cursor must be declared before this command type can be initialized");
     506             : 
     507             :         /* declare the cursor to allow following commands */
     508          10 :         check_call(ct_cursor, (cmd, CS_CURSOR_DECLARE, "test", CS_NULLTERM, "query", CS_NULLTERM, CS_UNUSED));
     509             : 
     510             :         /* name present */
     511          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_ROWS, "name", CS_NULLTERM, "text", CS_NULLTERM, (CS_INT) 1));
     512          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The name parameter must be NULL");
     513             : 
     514             :         /* invalid name length */
     515          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_ROWS, NULL, CS_NULLTERM, "text", CS_NULLTERM, (CS_INT) 1));
     516          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The namelen parameter must be set to CS_UNUSED");
     517             : 
     518          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_ROWS, NULL, CS_UNUSED, "text", CS_NULLTERM, (CS_INT) 1));
     519          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The text parameter must be NULL");
     520             : 
     521          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_ROWS, NULL, CS_UNUSED, NULL, CS_NULLTERM, (CS_INT) 1));
     522          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The tlen parameter must be set to CS_UNUSED");
     523             : 
     524             :         /* name present */
     525          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_OPEN, "name", CS_NULLTERM, "text", CS_NULLTERM, CS_UNUSED));
     526          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The name parameter must be NULL");
     527             : 
     528             :         /* name length present */
     529          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_OPEN, NULL, CS_NULLTERM, "text", CS_NULLTERM, CS_UNUSED));
     530          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The namelen parameter must be set to CS_UNUSED");
     531             : 
     532             :         /* text present */
     533          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_OPEN, NULL, CS_UNUSED, "text", CS_NULLTERM, CS_UNUSED));
     534          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The text parameter must be NULL");
     535             : 
     536             :         /* text length present */
     537          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_OPEN, NULL, CS_UNUSED, NULL, CS_NULLTERM, CS_UNUSED));
     538          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The tlen parameter must be set to CS_UNUSED");
     539             : 
     540             :         /* name, name length, text, text length all present */
     541          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_CLOSE, "name", CS_NULLTERM, "text", CS_NULLTERM, CS_DEALLOC));
     542          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The name parameter must be NULL");
     543             : 
     544             :         /* name length present */
     545          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_CLOSE, NULL, CS_NULLTERM, "text", CS_NULLTERM, CS_DEALLOC));
     546          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The namelen parameter must be set to CS_UNUSED");
     547             : 
     548             :         /* text present */
     549          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_CLOSE, NULL, CS_UNUSED, "text", CS_NULLTERM, CS_DEALLOC));
     550          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The text parameter must be NULL");
     551             : 
     552             :         /* text length present */
     553          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_CLOSE, NULL, CS_UNUSED, NULL, CS_NULLTERM, CS_DEALLOC));
     554          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The tlen parameter must be set to CS_UNUSED");
     555             : 
     556             :         /* name, name length, text, text length all present */
     557          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DEALLOC, "name", CS_NULLTERM, "text", CS_NULLTERM, CS_UNUSED));
     558          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The name parameter must be NULL");
     559             : 
     560             :         /* name length present */
     561          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DEALLOC, NULL, CS_NULLTERM, "text", CS_NULLTERM, CS_UNUSED));
     562          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The namelen parameter must be set to CS_UNUSED");
     563             : 
     564             :         /* text present */
     565          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DEALLOC, NULL, CS_UNUSED, "text", CS_NULLTERM, CS_UNUSED));
     566          10 :         check_last_message(CTMSG_CLIENT2, 0x01010108, "The text parameter must be NULL");
     567             : 
     568             :         /* text length present */
     569          10 :         check_fail(ct_cursor, (cmd, CS_CURSOR_DEALLOC, NULL, CS_UNUSED, NULL, CS_NULLTERM, CS_UNUSED));
     570          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The tlen parameter must be set to CS_UNUSED");
     571             : 
     572          10 : }
     573             : 
     574             : static void
     575          10 : test_ct_con_props(void)
     576             : {
     577             :         CS_CONNECTION *conn;
     578             : 
     579          10 :         check_call(ct_con_alloc, (ctx, &conn));
     580             : 
     581             :         /* wrong buffer length */
     582          10 :         check_fail(ct_con_props, (conn, CS_SET, CS_APPNAME, "app", -3, NULL));
     583          10 :         check_last_message(CTMSG_CLIENT, 0x01010105, " -3 given for parameter buflen");
     584             : 
     585             :         /* wrong buffer length, CS_UNUSED, it had a different behaviour */
     586          10 :         check_fail(ct_con_props, (conn, CS_SET, CS_APPNAME, "app", CS_UNUSED, NULL));
     587          10 :         check_last_message(CTMSG_CLIENT, 0x01010105, " given for parameter buflen");
     588             : 
     589          10 :         check_call(ct_con_drop, (conn));
     590             : 
     591          10 :         check_fail(ct_con_props, (NULL, CS_SET, CS_APPNAME, "app", 3, NULL));
     592          10 :         check_last_message(CTMSG_NONE, 0, NULL);
     593          10 : }
     594             : 
     595             : static void
     596          10 : test_ct_cmd_props(void)
     597             : {
     598             :         CS_INT props_value;
     599             : 
     600             :         /* wrong buffer length */
     601          10 :         check_fail(ct_cmd_props, (cmd, CS_GET, CS_CUR_STATUS, &props_value, sizeof(CS_INT), NULL));
     602          10 :         check_last_message(CTMSG_CLIENT2, 0x01010109, "The buflen parameter must be set to CS_UNUSED");
     603          10 : }
     604             : 
     605             : static void
     606          10 : test_cs_convert(void)
     607             : {
     608             :         CS_INT retlen;
     609             :         char outbuf[64];
     610             :         typedef struct format_test
     611             :         {
     612             :                 CS_INT datatype;
     613             :                 CS_INT format;
     614             :                 bool success;
     615             :         } format_test;
     616             : 
     617             :         static const format_test format_tests[] = {
     618             :                 {CS_CHAR_TYPE, CS_FMT_UNUSED, true},
     619             :                 {CS_CHAR_TYPE, CS_FMT_NULLTERM, true},
     620             :                 {CS_CHAR_TYPE, CS_FMT_PADNULL, true},
     621             :                 {CS_CHAR_TYPE, CS_FMT_PADBLANK, true},
     622             :                 {CS_CHAR_TYPE, CS_FMT_JUSTIFY_RT, false},
     623             :                 {CS_CHAR_TYPE, CS_FMT_STRIPBLANKS, false},
     624             : #if 0
     625             :                 /* supported by Sybase, not FreeTDS currently */
     626             :                 {CS_CHAR_TYPE, CS_FMT_SAFESTR, true},
     627             :                 {CS_CHAR_TYPE, CS_FMT_SUBS_ILL_CHAR, true},
     628             : #endif
     629             : 
     630             :                 {CS_BINARY_TYPE, CS_FMT_UNUSED, true},
     631             :                 {CS_BINARY_TYPE, CS_FMT_NULLTERM, false},
     632             :                 {CS_BINARY_TYPE, CS_FMT_PADNULL, true},
     633             :                 {CS_BINARY_TYPE, CS_FMT_PADBLANK, false},
     634             :                 {CS_BINARY_TYPE, CS_FMT_JUSTIFY_RT, false},
     635             :                 {CS_BINARY_TYPE, CS_FMT_STRIPBLANKS, false},
     636             :                 {CS_BINARY_TYPE, CS_FMT_SAFESTR, false},
     637             :                 {CS_BINARY_TYPE, CS_FMT_SUBS_ILL_CHAR, false},
     638             : 
     639             :                 {-1, -1, false},
     640             :         };
     641             :         const format_test *p_format_test;
     642          10 :         CS_NUMERIC num = { 1, 1, {0, 1,} };
     643             : 
     644             :         CS_DATAFMT destfmt, srcfmt;
     645             : 
     646          10 :         memset(&srcfmt, 0, sizeof(srcfmt));
     647          10 :         memset(&destfmt, 0, sizeof(destfmt));
     648             : 
     649             :         /* destdata == NULL */
     650          10 :         check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, NULL, &retlen));
     651          10 :         check_last_message(CTMSG_CSLIB, 0x2010104, "The parameter destdata cannot be NULL");
     652             : 
     653             :         /* destfmt == NULL */
     654          10 :         check_fail(cs_convert, (ctx, &srcfmt, "src", NULL, outbuf, &retlen));
     655          10 :         check_last_message(CTMSG_CSLIB, 0x2010104, "The parameter destfmt cannot be NULL");
     656             : 
     657             :         /* destdata == NULL && destfmt == NULL */
     658          10 :         check_fail(cs_convert, (ctx, &srcfmt, "src", NULL, NULL, &retlen));
     659          10 :         check_last_message(CTMSG_CSLIB, 0x2010104, "The parameter destfmt cannot be NULL");
     660             : 
     661             :         /* invalid source type */
     662          10 :         srcfmt.datatype = 1234;
     663          10 :         check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
     664          10 :         check_last_message(CTMSG_CSLIB, 0x2010110, "Conversion between 1234 and 0 datatypes is not supported");
     665          10 :         srcfmt.datatype = 0;
     666             : 
     667             :         /* invalid destination type */
     668          10 :         destfmt.datatype = 1234;
     669          10 :         check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
     670          10 :         check_last_message(CTMSG_CSLIB, 0x2010110, "Conversion between 0 and 1234 datatypes is not supported");
     671          10 :         destfmt.datatype = 0;
     672             : 
     673             :         /* not fixed and maxlength == 0 */
     674          10 :         check_call(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
     675             : 
     676             :         /* not fixed and maxlength <= 0 */
     677          10 :         destfmt.maxlength = -1;
     678          10 :         check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
     679          10 :         check_last_message(CTMSG_CSLIB, 0x2010112,
     680             :                            "An illegal value of -1 was placed in the maxlength field of the CS_DATAFMT structure");
     681          10 :         destfmt.maxlength = 0;
     682             : 
     683             :         /* invalid formats */
     684         150 :         for (p_format_test = format_tests; p_format_test->datatype >= 0; ++p_format_test) {
     685         140 :                 destfmt.datatype = p_format_test->datatype;
     686         140 :                 destfmt.format = p_format_test->format;
     687         140 :                 destfmt.maxlength = 20;
     688         140 :                 srcfmt.maxlength = 4;
     689         140 :                 if (p_format_test->success) {
     690          60 :                         check_call(cs_convert, (ctx, &srcfmt, "3234", &destfmt, outbuf, &retlen));
     691             :                 } else {
     692          80 :                         check_fail(cs_convert, (ctx, &srcfmt, "3234", &destfmt, outbuf, &retlen));
     693          80 :                         check_last_message(CTMSG_CSLIB, 0x2010112, "was placed in the format field of the CS_DATAFMT structure");
     694             :                 }
     695             :         }
     696          10 :         destfmt.format = CS_FMT_UNUSED;
     697          10 :         destfmt.maxlength = 0;
     698          10 :         srcfmt.maxlength = 0;
     699             : 
     700             :         /* test invalid scale/precision for numeric */
     701          10 :         destfmt.datatype = CS_NUMERIC_TYPE;
     702          10 :         destfmt.precision = 1;
     703          10 :         check_call(cs_convert, (ctx, &srcfmt, &num, &destfmt, outbuf, &retlen));
     704             : 
     705          10 :         destfmt.precision = 0;
     706          10 :         check_fail(cs_convert, (ctx, &srcfmt, &num, &destfmt, outbuf, &retlen));
     707          10 :         check_last_message(CTMSG_CSLIB, 0x2010112, "was placed in the precision field of the CS_DATAFMT structure");
     708             : 
     709          10 :         destfmt.precision = 78;
     710          10 :         check_fail(cs_convert, (ctx, &srcfmt, &num, &destfmt, outbuf, &retlen));
     711          10 :         check_last_message(CTMSG_CSLIB, 0x2010112, "was placed in the precision field of the CS_DATAFMT structure");
     712             : 
     713          10 :         destfmt.precision = 30;
     714          10 :         destfmt.scale = -1;
     715          10 :         check_fail(cs_convert, (ctx, &srcfmt, &num, &destfmt, outbuf, &retlen));
     716          10 :         check_last_message(CTMSG_CSLIB, 0x2010112, "was placed in the scale field of the CS_DATAFMT structure");
     717             : 
     718          10 :         destfmt.scale = 0;
     719          10 :         check_call(cs_convert, (ctx, &srcfmt, &num, &destfmt, outbuf, &retlen));
     720             : 
     721          10 :         destfmt.scale = 30;
     722          10 :         check_call(cs_convert, (ctx, &srcfmt, &num, &destfmt, outbuf, &retlen));
     723             : 
     724          10 :         destfmt.scale = 31;
     725          10 :         check_fail(cs_convert, (ctx, &srcfmt, &num, &destfmt, outbuf, &retlen));
     726          10 :         check_last_message(CTMSG_CSLIB, 0x2010112, "was placed in the scale field of the CS_DATAFMT structure");
     727          10 : }
     728             : 
     729             : static void
     730          10 : test_cs_dt_info(void)
     731             : {
     732             :         CS_LOCALE *locale;
     733          10 :         CS_INT i_value = CS_DATES_SHORT;
     734             :         CS_INT len;
     735             : 
     736          10 :         check_call(cs_loc_alloc, (ctx, &locale));
     737             : 
     738          10 :         check_call(cs_dt_info, (ctx, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, sizeof(i_value), NULL));
     739             : 
     740             :         /* no context  */
     741          10 :         check_fail(cs_dt_info, (NULL, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, sizeof(i_value), NULL));
     742          10 :         check_last_message(CTMSG_NONE, 0, NULL);
     743             : 
     744             :         /* wrong action */
     745          10 :         check_fail(cs_dt_info, (ctx, 1000, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, sizeof(i_value), NULL));
     746          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " 1000 was given for parameter action");
     747             : 
     748             :         /* wrong type, set */
     749          10 :         check_fail(cs_dt_info, (ctx, CS_SET, locale, 1000, CS_UNUSED, &i_value, sizeof(i_value), NULL));
     750          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " 1000 was given for parameter type");
     751             : 
     752             :         /* wrong type, get */
     753          10 :         len = sizeof(i_value);
     754          10 :         check_fail(cs_dt_info, (ctx, CS_GET, locale, 1000, CS_UNUSED, &i_value, sizeof(i_value), &len));
     755          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " 1000 was given for parameter type");
     756             : 
     757             :         /* wrong length  */
     758          10 :         check_fail(cs_dt_info, (ctx, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, -4, NULL));
     759          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " -4 was given for parameter buflen");
     760             : 
     761             :         /* CS_NULLTERM as length is not accepted */
     762          10 :         check_fail(cs_dt_info, (ctx, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, CS_NULLTERM, NULL));
     763          10 :         check_last_message(CTMSG_CSLIB, 0x02010106, " -9 was given for parameter buflen");
     764             : 
     765             :         /* any other length seems accepted */
     766          10 :         check_call(cs_dt_info, (ctx, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, 0, NULL));
     767          10 :         check_call(cs_dt_info, (ctx, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, 1, NULL));
     768          10 :         check_call(cs_dt_info, (ctx, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, 100, NULL));
     769             : 
     770             :         /* invalid values are also accepted */
     771          10 :         i_value = -10000;
     772          10 :         check_call(cs_dt_info, (ctx, CS_SET, locale, CS_DT_CONVFMT, CS_UNUSED, &i_value, sizeof(i_value), NULL));
     773             : 
     774          10 :         check_call(cs_loc_drop, (ctx, locale));
     775          10 : }

Generated by: LCOV version 1.13