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