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_send) \
12 : TEST(cs_config) \
13 : TEST(blk_init) \
14 : TEST(cs_loc_alloc) \
15 : TEST(cs_loc_drop) \
16 : TEST(cs_locale) \
17 : TEST(ct_dynamic) \
18 : TEST(ct_connect) \
19 : TEST(ct_command) \
20 : TEST(ct_cursor) \
21 : TEST(ct_con_props) \
22 : TEST(cs_convert)
23 :
24 : /* forward declare all tests */
25 : #undef TEST
26 : #define TEST(name) static void test_ ## name(void);
27 : ALL_TESTS
28 :
29 : static void
30 0 : report_wrong_error(int line)
31 : {
32 0 : fprintf(stderr, "%d:Wrong error type %d number %d (%#x)\n", line,
33 0 : ct_last_message.type, ct_last_message.number, ct_last_message.number);
34 0 : exit(1);
35 : }
36 :
37 : static CS_CONTEXT *ctx;
38 : static CS_CONNECTION *conn;
39 : static CS_COMMAND *cmd;
40 :
41 : int
42 10 : main(void)
43 : {
44 10 : int verbose = 1;
45 :
46 10 : printf("%s: Testing message callbacks\n", __FILE__);
47 : if (verbose) {
48 10 : printf("Trying login\n");
49 : }
50 10 : check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
51 :
52 10 : check_call(cs_config, (ctx, CS_SET, CS_MESSAGE_CB, (CS_VOID*) cslibmsg_cb, CS_UNUSED, NULL));
53 :
54 : /* set different callback for the connection */
55 10 : check_call(ct_callback, (NULL, conn, CS_SET, CS_CLIENTMSG_CB, (CS_VOID*) clientmsg_cb2));
56 :
57 : /* call all tests */
58 : #undef TEST
59 : #define TEST(name) test_ ## name();
60 10 : ALL_TESTS
61 :
62 : if (verbose) {
63 10 : printf("Trying logout\n");
64 : }
65 10 : check_call(try_ctlogout, (ctx, conn, cmd, verbose));
66 :
67 : if (verbose) {
68 10 : printf("Test succeeded\n");
69 : }
70 : return 0;
71 : }
72 :
73 : static void
74 560 : _check_fail(const char *name, CS_RETCODE ret, int line)
75 : {
76 560 : if (ret != CS_FAIL) {
77 0 : fprintf(stderr, "%s():%d: succeeded\n", name, line);
78 0 : exit(1);
79 : }
80 560 : }
81 : #define check_fail(func, args) do { \
82 : ct_reset_last_message(); \
83 : _check_fail(#func, func args, __LINE__); \
84 : } while(0)
85 :
86 : static void
87 560 : _check_last_message(ct_message_type type, CS_INT number, const char *msg, int line)
88 : {
89 560 : bool type_ok = true, number_ok = true, msg_ok = true;
90 :
91 560 : if (type == CTMSG_NONE && ct_last_message.type == type)
92 : return;
93 :
94 510 : type_ok = (ct_last_message.type == type);
95 510 : number_ok = (ct_last_message.number == number);
96 510 : if (msg && msg[0])
97 500 : msg_ok = (strstr(ct_last_message.text, msg) != NULL);
98 510 : if (!type_ok || !number_ok || !msg_ok)
99 0 : report_wrong_error(line);
100 : }
101 : #define check_last_message(type, number, msg) \
102 : _check_last_message(type, number, msg, __LINE__)
103 :
104 : static void
105 10 : test_ct_callback(void)
106 : {
107 : void *ptr;
108 :
109 : /* this should fail, context or connection should be not NULL */
110 10 : check_fail(ct_callback, (NULL, NULL, CS_SET, CS_SERVERMSG_CB, servermsg_cb));
111 10 : check_last_message(CTMSG_NONE, 0, NULL);
112 :
113 : /* this should fail, context and connection cannot be both not NULL */
114 10 : check_fail(ct_callback, (ctx, conn, CS_SET, CS_SERVERMSG_CB, servermsg_cb));
115 10 : check_last_message(CTMSG_CLIENT2, 0x01010133, NULL);
116 :
117 : /* this should fail, invalid action */
118 10 : check_fail(ct_callback, (ctx, NULL, 3, CS_SERVERMSG_CB, servermsg_cb));
119 10 : check_last_message(CTMSG_CLIENT, 0x01010105, "action");
120 :
121 : /* this should fail, invalid action */
122 10 : check_fail(ct_callback, (NULL, conn, 3, CS_SERVERMSG_CB, servermsg_cb));
123 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, "action");
124 :
125 : /* this should fail, invalid type */
126 10 : check_fail(ct_callback, (ctx, NULL, CS_SET, 20, servermsg_cb));
127 10 : check_last_message(CTMSG_CLIENT, 0x01010105, "type");
128 :
129 : /* this should fail, invalid type */
130 10 : check_fail(ct_callback, (NULL, conn, CS_SET, 20, servermsg_cb));
131 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, "type");
132 :
133 : /* NULL func getting it */
134 10 : check_fail(ct_callback, (NULL, conn, CS_GET, CS_CLIENTMSG_CB, NULL));
135 10 : check_last_message(CTMSG_CLIENT2, 0x01010103, "The parameter func cannot be NULL");
136 :
137 10 : check_fail(ct_callback, (NULL, conn, CS_GET, CS_SERVERMSG_CB, NULL));
138 10 : check_last_message(CTMSG_CLIENT2, 0x01010103, "The parameter func cannot be NULL");
139 :
140 : /* invalid type with action CS_GET */
141 10 : check_fail(ct_callback, (NULL, conn, CS_GET, 20, NULL));
142 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, "An illegal value of 20 given for parameter type");
143 :
144 10 : ptr = (char*)0 + 123;
145 10 : check_fail(ct_callback, (NULL, conn, CS_GET, 20, &ptr));
146 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, "An illegal value of 20 given for parameter type");
147 10 : if (ptr != (char*)0 + 123) {
148 0 : fprintf(stderr, "Invalid pointer %p\n", ptr);
149 0 : exit(1);
150 : }
151 10 : }
152 :
153 : static void
154 10 : test_ct_res_info(void)
155 : {
156 : CS_RETCODE ret;
157 : CS_INT result_type;
158 : CS_INT num_cols;
159 : CS_INT count;
160 :
161 10 : check_call(ct_command, (cmd, CS_LANG_CMD, "SELECT 'hi' AS greeting", CS_NULLTERM, CS_UNUSED));
162 10 : check_call(ct_send, (cmd));
163 :
164 10 : while ((ret = ct_results(cmd, &result_type)) == CS_SUCCEED) {
165 20 : switch (result_type) {
166 : case CS_CMD_SUCCEED:
167 : case CS_CMD_DONE:
168 : break;
169 10 : case CS_ROW_RESULT:
170 : /* this should fail, invalid number */
171 10 : check_fail(ct_res_info, (cmd, 1234, &num_cols, CS_UNUSED, NULL));
172 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, "operation");
173 :
174 30 : while ((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
175 10 : continue;
176 :
177 10 : if (ret != CS_END_DATA) {
178 0 : fprintf(stderr, "ct_fetch() unexpected return %d.\n", (int) ret);
179 0 : exit(1);
180 : }
181 : break;
182 0 : default:
183 0 : fprintf(stderr, "ct_results() unexpected result_type %d.\n", (int) result_type);
184 0 : exit(1);
185 : }
186 : }
187 10 : if (ret != CS_END_RESULTS) {
188 0 : fprintf(stderr, "ct_results() unexpected return %d.\n", (int) ret);
189 0 : exit(1);
190 : }
191 10 : }
192 :
193 : static void
194 10 : test_ct_send(void)
195 : {
196 : /* reset command to idle state */
197 10 : check_call(ct_cmd_drop, (cmd));
198 10 : check_call(ct_cmd_alloc, (conn, &cmd));
199 :
200 : /* this should fail, invalid command state */
201 10 : check_fail(ct_send, (cmd));
202 10 : check_last_message(CTMSG_CLIENT2, 0x0101019b, "idle");
203 10 : }
204 :
205 : static void
206 10 : test_cs_config(void)
207 : {
208 : /* a set of invalid, not accepted values */
209 : static const CS_INT invalid_values[] = {
210 : -1,
211 : -5,
212 : -200,
213 : CS_WILDCARD,
214 : CS_NO_LIMIT,
215 : CS_UNUSED,
216 : 0 /* terminator */
217 : };
218 : const CS_INT *p_invalid;
219 : CS_INT out_len;
220 : char out_buf[8];
221 :
222 10 : check_call(cs_config, (ctx, CS_SET, CS_USERDATA, (CS_VOID *)"test", CS_NULLTERM, NULL));
223 :
224 : /* check that value written does not have the NUL terminator */
225 10 : strcpy(out_buf, "123456");
226 10 : check_call(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 8, NULL));
227 10 : if (strcmp(out_buf, "test56") != 0) {
228 0 : fprintf(stderr, "Wrong output buffer '%s'\n", out_buf);
229 0 : exit(1);
230 : }
231 :
232 10 : check_call(cs_config, (ctx, CS_SET, CS_USERDATA, (CS_VOID *)"test123", 4, NULL));
233 :
234 : /* check that value written does not have more characters */
235 10 : strcpy(out_buf, "123456");
236 10 : check_call(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 8, NULL));
237 10 : if (strcmp(out_buf, "test56") != 0) {
238 0 : fprintf(stderr, "Wrong output buffer '%s'\n", out_buf);
239 0 : exit(1);
240 : }
241 :
242 60 : for (p_invalid = invalid_values; *p_invalid != 0; ++p_invalid) {
243 60 : check_fail(cs_config, (ctx, CS_SET, CS_USERDATA, (CS_VOID *)"test", *p_invalid, NULL));
244 60 : check_last_message(CTMSG_CSLIB, 0x02010106, "buflen");
245 : }
246 :
247 : /* wrong action */
248 10 : check_fail(cs_config, (ctx, 1000, CS_USERDATA, (CS_VOID *)"test", 4, NULL));
249 10 : check_last_message(CTMSG_CSLIB, 0x02010106, "action");
250 :
251 : /* wrong property */
252 10 : check_fail(cs_config, (ctx, CS_SET, 100000, NULL, CS_UNUSED, NULL));
253 10 : check_last_message(CTMSG_CSLIB, 0x02010106, "property");
254 :
255 : /* read exactly expected bytes */
256 10 : check_call(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 4, NULL));
257 :
258 : /* wrong buflen getting value */
259 10 : out_len = -123;
260 10 : check_fail(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, CS_NULLTERM, &out_len));
261 10 : check_last_message(CTMSG_CSLIB, 0x02010106, "buflen");
262 10 : if (out_len != -123) {
263 0 : fprintf(stderr, "Wrong buffer length returned\n");
264 0 : exit(1);
265 : }
266 :
267 : /* shorter buffer */
268 10 : out_len = -123;
269 10 : strcpy(out_buf, "123456");
270 10 : check_fail(cs_config, (ctx, CS_GET, CS_USERDATA, (CS_VOID *)out_buf, 2, &out_len));
271 10 : check_last_message(CTMSG_CSLIB, 0x02010102, " 2 bytes");
272 10 : if (out_len != 4) {
273 0 : fprintf(stderr, "Wrong buffer length returned\n");
274 0 : exit(1);
275 : }
276 10 : if (strcmp(out_buf, "123456") != 0) {
277 0 : fprintf(stderr, "Wrong buffer returned\n");
278 0 : exit(1);
279 : }
280 10 : }
281 :
282 : static void
283 10 : test_blk_init(void)
284 : {
285 : CS_BLKDESC *blkdesc;
286 10 : check_call(blk_alloc, (conn, BLK_VERSION_100, &blkdesc));
287 :
288 : /* invalid direction */
289 10 : check_fail(blk_init, (blkdesc, 100, "testname", CS_NULLTERM));
290 10 : check_last_message(CTMSG_CLIENT2, 0x0101010f, "CS_BLK_IN or CS_BLK_OUT");
291 :
292 : /* invalid tablename */
293 10 : check_fail(blk_init, (blkdesc, CS_BLK_IN, NULL, CS_NULLTERM));
294 10 : check_last_message(CTMSG_CLIENT2, 0x01010106, "tblname cannot be NULL");
295 :
296 : /* invalid tablename length */
297 10 : check_fail(blk_init, (blkdesc, CS_BLK_IN, "testname", -4));
298 10 : check_last_message(CTMSG_CLIENT2, 0x01010104, "tblnamelen has an illegal value of -4");
299 :
300 10 : check_call(blk_drop, (blkdesc));
301 10 : }
302 :
303 : static void
304 10 : test_cs_loc_alloc(void)
305 : {
306 : /* no context or locale */
307 10 : check_fail(cs_loc_alloc, (NULL, NULL));
308 10 : check_last_message(CTMSG_NONE, 0, NULL);
309 :
310 : /* no locale */
311 10 : check_fail(cs_loc_alloc, (ctx, NULL));
312 10 : check_last_message(CTMSG_CSLIB, 0x02010104, " loc_pointer cannot be NULL");
313 10 : }
314 :
315 : static void
316 10 : test_cs_loc_drop(void)
317 : {
318 : /* no context or locale */
319 10 : check_fail(cs_loc_drop, (NULL, NULL));
320 10 : check_last_message(CTMSG_NONE, 0, NULL);
321 :
322 : /* no locale */
323 10 : check_fail(cs_loc_drop, (ctx, NULL));
324 10 : check_last_message(CTMSG_CSLIB, 0x02010104, " locale cannot be NULL");
325 10 : }
326 :
327 : static void
328 10 : test_cs_locale(void)
329 : {
330 : CS_LOCALE *locale;
331 :
332 10 : check_call(cs_loc_alloc, (ctx, &locale));
333 :
334 10 : check_call(cs_locale, (ctx, CS_SET, locale, CS_SYB_CHARSET, "utf8", 4, NULL));
335 :
336 : /* no context */
337 10 : check_fail(cs_locale, (NULL, CS_SET, locale, CS_SYB_CHARSET, "utf8", 4, NULL));
338 10 : check_last_message(CTMSG_NONE, 0, NULL);
339 :
340 : /* no locale */
341 10 : check_fail(cs_locale, (ctx, CS_SET, NULL, CS_SYB_CHARSET, "utf8", 4, NULL));
342 10 : check_last_message(CTMSG_CSLIB, 0x02010104, " locale cannot be NULL");
343 :
344 : /* wrong action */
345 10 : check_fail(cs_locale, (ctx, 1000, locale, CS_SYB_CHARSET, "utf8", 4, NULL));
346 10 : check_last_message(CTMSG_CSLIB, 0x02010106, " 1000 was given for parameter action");
347 :
348 : /* wrong type */
349 10 : check_fail(cs_locale, (ctx, CS_SET, locale, 1000, "utf8", 4, NULL));
350 10 : check_last_message(CTMSG_CSLIB, 0x02010106, " 1000 was given for parameter type");
351 :
352 : /* wrong length */
353 10 : check_fail(cs_locale, (ctx, CS_SET, locale, CS_SYB_CHARSET, "utf8", -4, NULL));
354 10 : check_last_message(CTMSG_CSLIB, 0x02010106, " -4 was given for parameter buflen");
355 :
356 10 : check_call(cs_loc_drop, (ctx, locale));
357 10 : }
358 :
359 : static void
360 10 : test_ct_dynamic(void)
361 : {
362 : /* wrong type */
363 10 : check_fail(ct_dynamic, (cmd, 10000, "test", CS_NULLTERM, "query", CS_NULLTERM));
364 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " 10000 given for parameter type");
365 :
366 : /* wrong id length */
367 10 : check_fail(ct_dynamic, (cmd, CS_PREPARE, "test", -5, "query", CS_NULLTERM));
368 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -5 given for parameter idlen");
369 :
370 : /* wrong query length */
371 10 : check_fail(ct_dynamic, (cmd, CS_PREPARE, "test", CS_NULLTERM, "query", -6));
372 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -6 given for parameter buflen");
373 :
374 : /* wrong id and query length */
375 10 : check_fail(ct_dynamic, (cmd, CS_PREPARE, "test", -5, "query", -6));
376 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -5 given for parameter idlen");
377 :
378 : /* id not existing */
379 10 : check_fail(ct_dynamic, (cmd, CS_DEALLOC, "notexisting", CS_NULLTERM, NULL, CS_UNUSED));
380 10 : check_last_message(CTMSG_CLIENT2, 0x01010187, " specified id does not exist ");
381 :
382 : /* wrong id length */
383 10 : check_fail(ct_dynamic, (cmd, CS_DEALLOC, "notexisting", -7, NULL, CS_UNUSED));
384 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -7 given for parameter idlen");
385 10 : }
386 :
387 : static void
388 10 : test_ct_connect(void)
389 : {
390 : CS_CONNECTION *conn;
391 :
392 10 : check_call(ct_con_alloc, (ctx, &conn));
393 :
394 : /* wrong server name length */
395 10 : check_fail(ct_connect, (conn, "test", -5));
396 10 : check_last_message(CTMSG_CLIENT, 0x01010105, " -5 given for parameter snamelen");
397 :
398 10 : check_call(ct_con_drop, (conn));
399 10 : }
400 :
401 : static void
402 10 : test_ct_command(void)
403 : {
404 : /* wrong query length, CS_UNUSED, this was behaving differently */
405 10 : check_fail(ct_command, (cmd, CS_LANG_CMD, "test", CS_UNUSED, CS_UNUSED));
406 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " given for parameter buflen");
407 :
408 : /* wrong query length */
409 10 : check_fail(ct_command, (cmd, CS_LANG_CMD, "test", -7, CS_UNUSED));
410 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -7 given for parameter buflen");
411 :
412 : /* wrong query length, RPC */
413 10 : check_fail(ct_command, (cmd, CS_RPC_CMD, "test", -3, CS_UNUSED));
414 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -3 given for parameter buflen");
415 10 : }
416 :
417 : static void
418 10 : test_ct_cursor(void)
419 : {
420 : /* wrong name length */
421 10 : check_fail(ct_cursor, (cmd, CS_CURSOR_DECLARE, "test", -4, "query", CS_NULLTERM, CS_UNUSED));
422 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -4 given for parameter namelen");
423 :
424 : /* wrong query length */
425 10 : check_fail(ct_cursor, (cmd, CS_CURSOR_DECLARE, "test", CS_NULLTERM, "query", -3, CS_UNUSED));
426 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -3 given for parameter tlen");
427 :
428 : /* wrong name and query length */
429 10 : check_fail(ct_cursor, (cmd, CS_CURSOR_DECLARE, "test", -11, "query", -3, CS_UNUSED));
430 10 : check_last_message(CTMSG_CLIENT2, 0x01010105, " -11 given for parameter namelen");
431 10 : }
432 :
433 : static void
434 10 : test_ct_con_props(void)
435 : {
436 : CS_CONNECTION *conn;
437 :
438 10 : check_call(ct_con_alloc, (ctx, &conn));
439 :
440 : /* wrong buffer length */
441 10 : check_fail(ct_con_props, (conn, CS_SET, CS_APPNAME, "app", -3, NULL));
442 10 : check_last_message(CTMSG_CLIENT, 0x01010105, " -3 given for parameter buflen");
443 :
444 : /* wrong buffer length, CS_UNUSED, it had a different behaviour */
445 10 : check_fail(ct_con_props, (conn, CS_SET, CS_APPNAME, "app", CS_UNUSED, NULL));
446 10 : check_last_message(CTMSG_CLIENT, 0x01010105, " given for parameter buflen");
447 :
448 10 : check_call(ct_con_drop, (conn));
449 :
450 10 : check_fail(ct_con_props, (NULL, CS_SET, CS_APPNAME, "app", 3, NULL));
451 10 : check_last_message(CTMSG_NONE, 0, NULL);
452 10 : }
453 :
454 : static void
455 10 : test_cs_convert(void)
456 : {
457 : CS_INT retlen;
458 : char outbuf[32];
459 :
460 : CS_DATAFMT destfmt, srcfmt;
461 10 : memset(&srcfmt, 0, sizeof(srcfmt));
462 10 : memset(&destfmt, 0, sizeof(destfmt));
463 :
464 : /* destdata == NULL */
465 10 : check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, NULL, &retlen));
466 10 : check_last_message(CTMSG_CSLIB, 0x2010104, "The parameter destdata cannot be NULL");
467 :
468 : /* destfmt == NULL */
469 10 : check_fail(cs_convert, (ctx, &srcfmt, "src", NULL, outbuf, &retlen));
470 10 : check_last_message(CTMSG_CSLIB, 0x2010104, "The parameter destfmt cannot be NULL");
471 :
472 : /* destdata == NULL && destfmt == NULL */
473 10 : check_fail(cs_convert, (ctx, &srcfmt, "src", NULL, NULL, &retlen));
474 10 : check_last_message(CTMSG_CSLIB, 0x2010104, "The parameter destfmt cannot be NULL");
475 :
476 : /* invalid source type */
477 10 : srcfmt.datatype = 1234;
478 10 : check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
479 10 : check_last_message(CTMSG_CSLIB, 0x2010110, "Conversion between 1234 and 0 datatypes is not supported");
480 10 : srcfmt.datatype = 0;
481 :
482 : /* invalid destination type */
483 10 : destfmt.datatype = 1234;
484 10 : check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
485 10 : check_last_message(CTMSG_CSLIB, 0x2010110, "Conversion between 0 and 1234 datatypes is not supported");
486 10 : destfmt.datatype = 0;
487 :
488 : /* not fixed and maxlength == 0 */
489 10 : check_call(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
490 :
491 : /* not fixed and maxlength <= 0 */
492 10 : destfmt.maxlength = -1;
493 10 : check_fail(cs_convert, (ctx, &srcfmt, "src", &destfmt, outbuf, &retlen));
494 10 : check_last_message(CTMSG_CSLIB, 0x2010112,
495 : "An illegal value of -1 was placed in the maxlength field of the CS_DATAFMT structure");
496 : destfmt.maxlength = 0;
497 10 : }
|