]>
git.saurik.com Git - redis.git/blob - deps/hiredis/test.c
14 enum connection_type
{
20 enum connection_type type
;
32 /* The following lines make up our testing "framework" :) */
33 static int tests
= 0, fails
= 0;
34 #define test(_s) { printf("#%02d ", ++tests); printf(_s); }
35 #define test_cond(_c) if(_c) printf("\033[0;32mPASSED\033[0;0m\n"); else {printf("\033[0;31mFAILED\033[0;0m\n"); fails++;}
37 static long long usec(void) {
39 gettimeofday(&tv
,NULL
);
40 return (((long long)tv
.tv_sec
)*1000000)+tv
.tv_usec
;
43 static redisContext
*select_database(redisContext
*c
) {
46 /* Switch to DB 9 for testing, now that we know we can chat. */
47 reply
= redisCommand(c
,"SELECT 9");
48 assert(reply
!= NULL
);
49 freeReplyObject(reply
);
51 /* Make sure the DB is emtpy */
52 reply
= redisCommand(c
,"DBSIZE");
53 assert(reply
!= NULL
);
54 if (reply
->type
== REDIS_REPLY_INTEGER
&& reply
->integer
== 0) {
55 /* Awesome, DB 9 is empty and we can continue. */
56 freeReplyObject(reply
);
58 printf("Database #9 is not empty, test can not continue\n");
65 static void disconnect(redisContext
*c
) {
68 /* Make sure we're on DB 9. */
69 reply
= redisCommand(c
,"SELECT 9");
70 assert(reply
!= NULL
);
71 freeReplyObject(reply
);
72 reply
= redisCommand(c
,"FLUSHDB");
73 assert(reply
!= NULL
);
74 freeReplyObject(reply
);
76 /* Free the context as well. */
80 static redisContext
*connect(struct config config
) {
81 redisContext
*c
= NULL
;
83 if (config
.type
== CONN_TCP
) {
84 c
= redisConnect(config
.tcp
.host
, config
.tcp
.port
);
85 } else if (config
.type
== CONN_UNIX
) {
86 c
= redisConnectUnix(config
.unix
.path
);
92 printf("Connection error: %s\n", c
->errstr
);
96 return select_database(c
);
99 static void test_format_commands(void) {
103 test("Format command without interpolation: ");
104 len
= redisFormatCommand(&cmd
,"SET foo bar");
105 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len
) == 0 &&
106 len
== 4+4+(3+2)+4+(3+2)+4+(3+2));
109 test("Format command with %%s string interpolation: ");
110 len
= redisFormatCommand(&cmd
,"SET %s %s","foo","bar");
111 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len
) == 0 &&
112 len
== 4+4+(3+2)+4+(3+2)+4+(3+2));
115 test("Format command with %%s and an empty string: ");
116 len
= redisFormatCommand(&cmd
,"SET %s %s","foo","");
117 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len
) == 0 &&
118 len
== 4+4+(3+2)+4+(3+2)+4+(0+2));
121 test("Format command with an empty string in between proper interpolations: ");
122 len
= redisFormatCommand(&cmd
,"SET %s %s","","foo");
123 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$0\r\n\r\n$3\r\nfoo\r\n",len
) == 0 &&
124 len
== 4+4+(3+2)+4+(0+2)+4+(3+2));
127 test("Format command with %%b string interpolation: ");
128 len
= redisFormatCommand(&cmd
,"SET %b %b","foo",3,"b\0r",3);
129 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len
) == 0 &&
130 len
== 4+4+(3+2)+4+(3+2)+4+(3+2));
133 test("Format command with %%b and an empty string: ");
134 len
= redisFormatCommand(&cmd
,"SET %b %b","foo",3,"",0);
135 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len
) == 0 &&
136 len
== 4+4+(3+2)+4+(3+2)+4+(0+2));
139 test("Format command with literal %%: ");
140 len
= redisFormatCommand(&cmd
,"SET %% %%");
141 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$1\r\n%\r\n$1\r\n%\r\n",len
) == 0 &&
142 len
== 4+4+(3+2)+4+(1+2)+4+(1+2));
145 /* Vararg width depends on the type. These tests make sure that the
146 * width is correctly determined using the format and subsequent varargs
147 * can correctly be interpolated. */
148 #define INTEGER_WIDTH_TEST(fmt, type) do { \
150 test("Format command with printf-delegation (" #type "): "); \
151 len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \
152 test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \
153 len == 4+5+(12+2)+4+(9+2)); \
157 #define FLOAT_WIDTH_TEST(type) do { \
158 type value = 123.0; \
159 test("Format command with printf-delegation (" #type "): "); \
160 len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \
161 test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \
162 len == 4+5+(12+2)+4+(9+2)); \
166 INTEGER_WIDTH_TEST("d", int);
167 INTEGER_WIDTH_TEST("hhd", char);
168 INTEGER_WIDTH_TEST("hd", short);
169 INTEGER_WIDTH_TEST("ld", long);
170 INTEGER_WIDTH_TEST("lld", long long);
171 INTEGER_WIDTH_TEST("u", unsigned int);
172 INTEGER_WIDTH_TEST("hhu", unsigned char);
173 INTEGER_WIDTH_TEST("hu", unsigned short);
174 INTEGER_WIDTH_TEST("lu", unsigned long);
175 INTEGER_WIDTH_TEST("llu", unsigned long long);
176 FLOAT_WIDTH_TEST(float);
177 FLOAT_WIDTH_TEST(double);
179 test("Format command with invalid printf format: ");
180 len
= redisFormatCommand(&cmd
,"key:%08p %b",(void*)1234,"foo",3);
181 test_cond(len
== -1);
185 argv
[1] = "foo\0xxx";
187 size_t lens
[3] = { 3, 7, 3 };
190 test("Format command by passing argc/argv without lengths: ");
191 len
= redisFormatCommandArgv(&cmd
,argc
,argv
,NULL
);
192 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len
) == 0 &&
193 len
== 4+4+(3+2)+4+(3+2)+4+(3+2));
196 test("Format command by passing argc/argv with lengths: ");
197 len
= redisFormatCommandArgv(&cmd
,argc
,argv
,lens
);
198 test_cond(strncmp(cmd
,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len
) == 0 &&
199 len
== 4+4+(3+2)+4+(7+2)+4+(3+2));
203 static void test_reply_reader(void) {
208 test("Error handling in reply parser: ");
209 reader
= redisReaderCreate();
210 redisReaderFeed(reader
,(char*)"@foo\r\n",6);
211 ret
= redisReaderGetReply(reader
,NULL
);
212 test_cond(ret
== REDIS_ERR
&&
213 strcasecmp(reader
->errstr
,"Protocol error, got \"@\" as reply type byte") == 0);
214 redisReaderFree(reader
);
216 /* when the reply already contains multiple items, they must be free'd
217 * on an error. valgrind will bark when this doesn't happen. */
218 test("Memory cleanup in reply parser: ");
219 reader
= redisReaderCreate();
220 redisReaderFeed(reader
,(char*)"*2\r\n",4);
221 redisReaderFeed(reader
,(char*)"$5\r\nhello\r\n",11);
222 redisReaderFeed(reader
,(char*)"@foo\r\n",6);
223 ret
= redisReaderGetReply(reader
,NULL
);
224 test_cond(ret
== REDIS_ERR
&&
225 strcasecmp(reader
->errstr
,"Protocol error, got \"@\" as reply type byte") == 0);
226 redisReaderFree(reader
);
228 test("Set error on nested multi bulks with depth > 2: ");
229 reader
= redisReaderCreate();
230 redisReaderFeed(reader
,(char*)"*1\r\n",4);
231 redisReaderFeed(reader
,(char*)"*1\r\n",4);
232 redisReaderFeed(reader
,(char*)"*1\r\n",4);
233 redisReaderFeed(reader
,(char*)"*1\r\n",4);
234 ret
= redisReaderGetReply(reader
,NULL
);
235 test_cond(ret
== REDIS_ERR
&&
236 strncasecmp(reader
->errstr
,"No support for",14) == 0);
237 redisReaderFree(reader
);
239 test("Works with NULL functions for reply: ");
240 reader
= redisReaderCreate();
242 redisReaderFeed(reader
,(char*)"+OK\r\n",5);
243 ret
= redisReaderGetReply(reader
,&reply
);
244 test_cond(ret
== REDIS_OK
&& reply
== (void*)REDIS_REPLY_STATUS
);
245 redisReaderFree(reader
);
247 test("Works when a single newline (\\r\\n) covers two calls to feed: ");
248 reader
= redisReaderCreate();
250 redisReaderFeed(reader
,(char*)"+OK\r",4);
251 ret
= redisReaderGetReply(reader
,&reply
);
252 assert(ret
== REDIS_OK
&& reply
== NULL
);
253 redisReaderFeed(reader
,(char*)"\n",1);
254 ret
= redisReaderGetReply(reader
,&reply
);
255 test_cond(ret
== REDIS_OK
&& reply
== (void*)REDIS_REPLY_STATUS
);
256 redisReaderFree(reader
);
258 test("Don't reset state after protocol error: ");
259 reader
= redisReaderCreate();
261 redisReaderFeed(reader
,(char*)"x",1);
262 ret
= redisReaderGetReply(reader
,&reply
);
263 assert(ret
== REDIS_ERR
);
264 ret
= redisReaderGetReply(reader
,&reply
);
265 test_cond(ret
== REDIS_ERR
&& reply
== NULL
);
266 redisReaderFree(reader
);
268 /* Regression test for issue #45 on GitHub. */
269 test("Don't do empty allocation for empty multi bulk: ");
270 reader
= redisReaderCreate();
271 redisReaderFeed(reader
,(char*)"*0\r\n",4);
272 ret
= redisReaderGetReply(reader
,&reply
);
273 test_cond(ret
== REDIS_OK
&&
274 ((redisReply
*)reply
)->type
== REDIS_REPLY_ARRAY
&&
275 ((redisReply
*)reply
)->elements
== 0);
276 freeReplyObject(reply
);
277 redisReaderFree(reader
);
280 static void test_blocking_connection_errors(void) {
283 test("Returns error when host cannot be resolved: ");
284 c
= redisConnect((char*)"idontexist.local", 6379);
285 test_cond(c
->err
== REDIS_ERR_OTHER
&&
286 (strcmp(c
->errstr
,"Name or service not known") == 0 ||
287 strcmp(c
->errstr
,"Can't resolve: idontexist.local") == 0));
290 test("Returns error when the port is not open: ");
291 c
= redisConnect((char*)"localhost", 1);
292 test_cond(c
->err
== REDIS_ERR_IO
&&
293 strcmp(c
->errstr
,"Connection refused") == 0);
296 test("Returns error when the unix socket path doesn't accept connections: ");
297 c
= redisConnectUnix((char*)"/tmp/idontexist.sock");
298 test_cond(c
->err
== REDIS_ERR_IO
); /* Don't care about the message... */
302 static void test_blocking_connection(struct config config
) {
308 test("Is able to deliver commands: ");
309 reply
= redisCommand(c
,"PING");
310 test_cond(reply
->type
== REDIS_REPLY_STATUS
&&
311 strcasecmp(reply
->str
,"pong") == 0)
312 freeReplyObject(reply
);
314 test("Is a able to send commands verbatim: ");
315 reply
= redisCommand(c
,"SET foo bar");
316 test_cond (reply
->type
== REDIS_REPLY_STATUS
&&
317 strcasecmp(reply
->str
,"ok") == 0)
318 freeReplyObject(reply
);
320 test("%%s String interpolation works: ");
321 reply
= redisCommand(c
,"SET %s %s","foo","hello world");
322 freeReplyObject(reply
);
323 reply
= redisCommand(c
,"GET foo");
324 test_cond(reply
->type
== REDIS_REPLY_STRING
&&
325 strcmp(reply
->str
,"hello world") == 0);
326 freeReplyObject(reply
);
328 test("%%b String interpolation works: ");
329 reply
= redisCommand(c
,"SET %b %b","foo",3,"hello\x00world",11);
330 freeReplyObject(reply
);
331 reply
= redisCommand(c
,"GET foo");
332 test_cond(reply
->type
== REDIS_REPLY_STRING
&&
333 memcmp(reply
->str
,"hello\x00world",11) == 0)
335 test("Binary reply length is correct: ");
336 test_cond(reply
->len
== 11)
337 freeReplyObject(reply
);
339 test("Can parse nil replies: ");
340 reply
= redisCommand(c
,"GET nokey");
341 test_cond(reply
->type
== REDIS_REPLY_NIL
)
342 freeReplyObject(reply
);
345 test("Can parse integer replies: ");
346 reply
= redisCommand(c
,"INCR mycounter");
347 test_cond(reply
->type
== REDIS_REPLY_INTEGER
&& reply
->integer
== 1)
348 freeReplyObject(reply
);
350 test("Can parse multi bulk replies: ");
351 freeReplyObject(redisCommand(c
,"LPUSH mylist foo"));
352 freeReplyObject(redisCommand(c
,"LPUSH mylist bar"));
353 reply
= redisCommand(c
,"LRANGE mylist 0 -1");
354 test_cond(reply
->type
== REDIS_REPLY_ARRAY
&&
355 reply
->elements
== 2 &&
356 !memcmp(reply
->element
[0]->str
,"bar",3) &&
357 !memcmp(reply
->element
[1]->str
,"foo",3))
358 freeReplyObject(reply
);
360 /* m/e with multi bulk reply *before* other reply.
361 * specifically test ordering of reply items to parse. */
362 test("Can handle nested multi bulk replies: ");
363 freeReplyObject(redisCommand(c
,"MULTI"));
364 freeReplyObject(redisCommand(c
,"LRANGE mylist 0 -1"));
365 freeReplyObject(redisCommand(c
,"PING"));
366 reply
= (redisCommand(c
,"EXEC"));
367 test_cond(reply
->type
== REDIS_REPLY_ARRAY
&&
368 reply
->elements
== 2 &&
369 reply
->element
[0]->type
== REDIS_REPLY_ARRAY
&&
370 reply
->element
[0]->elements
== 2 &&
371 !memcmp(reply
->element
[0]->element
[0]->str
,"bar",3) &&
372 !memcmp(reply
->element
[0]->element
[1]->str
,"foo",3) &&
373 reply
->element
[1]->type
== REDIS_REPLY_STATUS
&&
374 strcasecmp(reply
->element
[1]->str
,"pong") == 0);
375 freeReplyObject(reply
);
380 static void test_blocking_io_errors(struct config config
) {
386 /* Connect to target given by config. */
389 /* Find out Redis version to determine the path for the next test */
390 const char *field
= "redis_version:";
393 reply
= redisCommand(c
,"INFO");
394 p
= strstr(reply
->str
,field
);
395 major
= strtol(p
+strlen(field
),&eptr
,10);
396 p
= eptr
+1; /* char next to the first "." */
397 minor
= strtol(p
,&eptr
,10);
398 freeReplyObject(reply
);
401 test("Returns I/O error when the connection is lost: ");
402 reply
= redisCommand(c
,"QUIT");
403 if (major
>= 2 && minor
> 0) {
404 /* > 2.0 returns OK on QUIT and read() should be issued once more
405 * to know the descriptor is at EOF. */
406 test_cond(strcasecmp(reply
->str
,"OK") == 0 &&
407 redisGetReply(c
,&_reply
) == REDIS_ERR
);
408 freeReplyObject(reply
);
410 test_cond(reply
== NULL
);
413 /* On 2.0, QUIT will cause the connection to be closed immediately and
414 * the read(2) for the reply on QUIT will set the error to EOF.
415 * On >2.0, QUIT will return with OK and another read(2) needed to be
416 * issued to find out the socket was closed by the server. In both
417 * conditions, the error will be set to EOF. */
418 assert(c
->err
== REDIS_ERR_EOF
&&
419 strcmp(c
->errstr
,"Server closed the connection") == 0);
423 test("Returns I/O error on socket timeout: ");
424 struct timeval tv
= { 0, 1000 };
425 assert(redisSetTimeout(c
,tv
) == REDIS_OK
);
426 test_cond(redisGetReply(c
,&_reply
) == REDIS_ERR
&&
427 c
->err
== REDIS_ERR_IO
&& errno
== EAGAIN
);
431 static void test_throughput(struct config config
) {
432 redisContext
*c
= connect(config
);
433 redisReply
**replies
;
437 test("Throughput:\n");
438 for (i
= 0; i
< 500; i
++)
439 freeReplyObject(redisCommand(c
,"LPUSH mylist foo"));
442 replies
= malloc(sizeof(redisReply
*)*num
);
444 for (i
= 0; i
< num
; i
++) {
445 replies
[i
] = redisCommand(c
,"PING");
446 assert(replies
[i
] != NULL
&& replies
[i
]->type
== REDIS_REPLY_STATUS
);
449 for (i
= 0; i
< num
; i
++) freeReplyObject(replies
[i
]);
451 printf("\t(%dx PING: %.3fs)\n", num
, (t2
-t1
)/1000000.0);
453 replies
= malloc(sizeof(redisReply
*)*num
);
455 for (i
= 0; i
< num
; i
++) {
456 replies
[i
] = redisCommand(c
,"LRANGE mylist 0 499");
457 assert(replies
[i
] != NULL
&& replies
[i
]->type
== REDIS_REPLY_ARRAY
);
458 assert(replies
[i
] != NULL
&& replies
[i
]->elements
== 500);
461 for (i
= 0; i
< num
; i
++) freeReplyObject(replies
[i
]);
463 printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num
, (t2
-t1
)/1000000.0);
466 replies
= malloc(sizeof(redisReply
*)*num
);
467 for (i
= 0; i
< num
; i
++)
468 redisAppendCommand(c
,"PING");
470 for (i
= 0; i
< num
; i
++) {
471 assert(redisGetReply(c
, (void*)&replies
[i
]) == REDIS_OK
);
472 assert(replies
[i
] != NULL
&& replies
[i
]->type
== REDIS_REPLY_STATUS
);
475 for (i
= 0; i
< num
; i
++) freeReplyObject(replies
[i
]);
477 printf("\t(%dx PING (pipelined): %.3fs)\n", num
, (t2
-t1
)/1000000.0);
479 replies
= malloc(sizeof(redisReply
*)*num
);
480 for (i
= 0; i
< num
; i
++)
481 redisAppendCommand(c
,"LRANGE mylist 0 499");
483 for (i
= 0; i
< num
; i
++) {
484 assert(redisGetReply(c
, (void*)&replies
[i
]) == REDIS_OK
);
485 assert(replies
[i
] != NULL
&& replies
[i
]->type
== REDIS_REPLY_ARRAY
);
486 assert(replies
[i
] != NULL
&& replies
[i
]->elements
== 500);
489 for (i
= 0; i
< num
; i
++) freeReplyObject(replies
[i
]);
491 printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num
, (t2
-t1
)/1000000.0);
496 // static long __test_callback_flags = 0;
497 // static void __test_callback(redisContext *c, void *privdata) {
499 // /* Shift to detect execution order */
500 // __test_callback_flags <<= 8;
501 // __test_callback_flags |= (long)privdata;
504 // static void __test_reply_callback(redisContext *c, redisReply *reply, void *privdata) {
506 // /* Shift to detect execution order */
507 // __test_callback_flags <<= 8;
508 // __test_callback_flags |= (long)privdata;
509 // if (reply) freeReplyObject(reply);
512 // static redisContext *__connect_nonblock() {
513 // /* Reset callback flags */
514 // __test_callback_flags = 0;
515 // return redisConnectNonBlock("127.0.0.1", port, NULL);
518 // static void test_nonblocking_connection() {
522 // test("Calls command callback when command is issued: ");
523 // c = __connect_nonblock();
524 // redisSetCommandCallback(c,__test_callback,(void*)1);
525 // redisCommand(c,"PING");
526 // test_cond(__test_callback_flags == 1);
529 // test("Calls disconnect callback on redisDisconnect: ");
530 // c = __connect_nonblock();
531 // redisSetDisconnectCallback(c,__test_callback,(void*)2);
532 // redisDisconnect(c);
533 // test_cond(__test_callback_flags == 2);
536 // test("Calls disconnect callback and free callback on redisFree: ");
537 // c = __connect_nonblock();
538 // redisSetDisconnectCallback(c,__test_callback,(void*)2);
539 // redisSetFreeCallback(c,__test_callback,(void*)4);
541 // test_cond(__test_callback_flags == ((2 << 8) | 4));
543 // test("redisBufferWrite against empty write buffer: ");
544 // c = __connect_nonblock();
545 // test_cond(redisBufferWrite(c,&wdone) == REDIS_OK && wdone == 1);
548 // test("redisBufferWrite against not yet connected fd: ");
549 // c = __connect_nonblock();
550 // redisCommand(c,"PING");
551 // test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
552 // strncmp(c->error,"write:",6) == 0);
555 // test("redisBufferWrite against closed fd: ");
556 // c = __connect_nonblock();
557 // redisCommand(c,"PING");
558 // redisDisconnect(c);
559 // test_cond(redisBufferWrite(c,NULL) == REDIS_ERR &&
560 // strncmp(c->error,"write:",6) == 0);
563 // test("Process callbacks in the right sequence: ");
564 // c = __connect_nonblock();
565 // redisCommandWithCallback(c,__test_reply_callback,(void*)1,"PING");
566 // redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
567 // redisCommandWithCallback(c,__test_reply_callback,(void*)3,"PING");
569 // /* Write output buffer */
573 // redisBufferWrite(c,&wdone);
576 // /* Read until at least one callback is executed (the 3 replies will
577 // * arrive in a single packet, causing all callbacks to be executed in
578 // * a single pass). */
579 // while(__test_callback_flags == 0) {
580 // assert(redisBufferRead(c) == REDIS_OK);
581 // redisProcessCallbacks(c);
583 // test_cond(__test_callback_flags == 0x010203);
586 // test("redisDisconnect executes pending callbacks with NULL reply: ");
587 // c = __connect_nonblock();
588 // redisSetDisconnectCallback(c,__test_callback,(void*)1);
589 // redisCommandWithCallback(c,__test_reply_callback,(void*)2,"PING");
590 // redisDisconnect(c);
591 // test_cond(__test_callback_flags == 0x0201);
595 int main(int argc
, char **argv
) {
596 struct config cfg
= {
602 .path
= "/tmp/redis.sock"
607 /* Ignore broken pipe signal (for I/O error tests). */
608 signal(SIGPIPE
, SIG_IGN
);
610 /* Parse command line options. */
613 if (argc
>= 2 && !strcmp(argv
[0],"-h")) {
615 cfg
.tcp
.host
= argv
[0];
616 } else if (argc
>= 2 && !strcmp(argv
[0],"-p")) {
618 cfg
.tcp
.port
= atoi(argv
[0]);
619 } else if (argc
>= 2 && !strcmp(argv
[0],"-s")) {
621 cfg
.unix
.path
= argv
[0];
622 } else if (argc
>= 1 && !strcmp(argv
[0],"--skip-throughput")) {
625 fprintf(stderr
, "Invalid argument: %s\n", argv
[0]);
631 test_format_commands();
633 test_blocking_connection_errors();
635 printf("\nTesting against TCP connection (%s:%d):\n", cfg
.tcp
.host
, cfg
.tcp
.port
);
637 test_blocking_connection(cfg
);
638 test_blocking_io_errors(cfg
);
639 if (throughput
) test_throughput(cfg
);
641 printf("\nTesting against Unix socket connection (%s):\n", cfg
.unix
.path
);
642 cfg
.type
= CONN_UNIX
;
643 test_blocking_connection(cfg
);
644 test_blocking_io_errors(cfg
);
645 if (throughput
) test_throughput(cfg
);
648 printf("*** %d TESTS FAILED ***\n", fails
);
652 printf("ALL TESTS PASSED\n");