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 : }
|