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