hiredis 0.5.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Rakefile +8 -6
- data/ext/hiredis_ext/connection.c +4 -3
- data/ext/hiredis_ext/extconf.rb +25 -10
- data/ext/hiredis_ext/reader.c +12 -6
- data/lib/hiredis/version.rb +1 -1
- data/vendor/hiredis/Makefile +119 -54
- data/vendor/hiredis/async.c +121 -27
- data/vendor/hiredis/async.h +5 -0
- data/vendor/hiredis/dict.c +2 -2
- data/vendor/hiredis/fmacros.h +5 -9
- data/vendor/hiredis/hiredis.c +275 -554
- data/vendor/hiredis/hiredis.h +64 -75
- data/vendor/hiredis/net.c +242 -56
- data/vendor/hiredis/net.h +12 -10
- data/vendor/hiredis/read.c +598 -0
- data/vendor/hiredis/read.h +111 -0
- data/vendor/hiredis/sds.c +847 -180
- data/vendor/hiredis/sds.h +203 -18
- data/vendor/hiredis/sdsalloc.h +42 -0
- data/vendor/hiredis/test.c +286 -19
- data/vendor/hiredis/win32.h +42 -0
- metadata +46 -28
- data/lib/hiredis/errors.rb +0 -5
data/vendor/hiredis/test.c
CHANGED
@@ -8,12 +8,15 @@
|
|
8
8
|
#include <unistd.h>
|
9
9
|
#include <signal.h>
|
10
10
|
#include <errno.h>
|
11
|
+
#include <limits.h>
|
11
12
|
|
12
13
|
#include "hiredis.h"
|
14
|
+
#include "net.h"
|
13
15
|
|
14
16
|
enum connection_type {
|
15
17
|
CONN_TCP,
|
16
|
-
CONN_UNIX
|
18
|
+
CONN_UNIX,
|
19
|
+
CONN_FD
|
17
20
|
};
|
18
21
|
|
19
22
|
struct config {
|
@@ -22,11 +25,12 @@ struct config {
|
|
22
25
|
struct {
|
23
26
|
const char *host;
|
24
27
|
int port;
|
28
|
+
struct timeval timeout;
|
25
29
|
} tcp;
|
26
30
|
|
27
31
|
struct {
|
28
32
|
const char *path;
|
29
|
-
}
|
33
|
+
} unix_sock;
|
30
34
|
};
|
31
35
|
|
32
36
|
/* The following lines make up our testing "framework" :) */
|
@@ -40,6 +44,13 @@ static long long usec(void) {
|
|
40
44
|
return (((long long)tv.tv_sec)*1000000)+tv.tv_usec;
|
41
45
|
}
|
42
46
|
|
47
|
+
/* The assert() calls below have side effects, so we need assert()
|
48
|
+
* even if we are compiling without asserts (-DNDEBUG). */
|
49
|
+
#ifdef NDEBUG
|
50
|
+
#undef assert
|
51
|
+
#define assert(e) (void)(e)
|
52
|
+
#endif
|
53
|
+
|
43
54
|
static redisContext *select_database(redisContext *c) {
|
44
55
|
redisReply *reply;
|
45
56
|
|
@@ -62,7 +73,7 @@ static redisContext *select_database(redisContext *c) {
|
|
62
73
|
return c;
|
63
74
|
}
|
64
75
|
|
65
|
-
static
|
76
|
+
static int disconnect(redisContext *c, int keep_fd) {
|
66
77
|
redisReply *reply;
|
67
78
|
|
68
79
|
/* Make sure we're on DB 9. */
|
@@ -73,8 +84,11 @@ static void disconnect(redisContext *c) {
|
|
73
84
|
assert(reply != NULL);
|
74
85
|
freeReplyObject(reply);
|
75
86
|
|
76
|
-
/* Free the context as well. */
|
87
|
+
/* Free the context as well, but keep the fd if requested. */
|
88
|
+
if (keep_fd)
|
89
|
+
return redisFreeKeepFd(c);
|
77
90
|
redisFree(c);
|
91
|
+
return -1;
|
78
92
|
}
|
79
93
|
|
80
94
|
static redisContext *connect(struct config config) {
|
@@ -83,13 +97,25 @@ static redisContext *connect(struct config config) {
|
|
83
97
|
if (config.type == CONN_TCP) {
|
84
98
|
c = redisConnect(config.tcp.host, config.tcp.port);
|
85
99
|
} else if (config.type == CONN_UNIX) {
|
86
|
-
c = redisConnectUnix(config.
|
100
|
+
c = redisConnectUnix(config.unix_sock.path);
|
101
|
+
} else if (config.type == CONN_FD) {
|
102
|
+
/* Create a dummy connection just to get an fd to inherit */
|
103
|
+
redisContext *dummy_ctx = redisConnectUnix(config.unix_sock.path);
|
104
|
+
if (dummy_ctx) {
|
105
|
+
int fd = disconnect(dummy_ctx, 1);
|
106
|
+
printf("Connecting to inherited fd %d\n", fd);
|
107
|
+
c = redisConnectFd(fd);
|
108
|
+
}
|
87
109
|
} else {
|
88
110
|
assert(NULL);
|
89
111
|
}
|
90
112
|
|
91
|
-
if (c
|
113
|
+
if (c == NULL) {
|
114
|
+
printf("Connection error: can't allocate redis context\n");
|
115
|
+
exit(1);
|
116
|
+
} else if (c->err) {
|
92
117
|
printf("Connection error: %s\n", c->errstr);
|
118
|
+
redisFree(c);
|
93
119
|
exit(1);
|
94
120
|
}
|
95
121
|
|
@@ -125,13 +151,13 @@ static void test_format_commands(void) {
|
|
125
151
|
free(cmd);
|
126
152
|
|
127
153
|
test("Format command with %%b string interpolation: ");
|
128
|
-
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3);
|
154
|
+
len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3);
|
129
155
|
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
156
|
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
|
131
157
|
free(cmd);
|
132
158
|
|
133
159
|
test("Format command with %%b and an empty string: ");
|
134
|
-
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"",0);
|
160
|
+
len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0);
|
135
161
|
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
162
|
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
|
137
163
|
free(cmd);
|
@@ -177,7 +203,7 @@ static void test_format_commands(void) {
|
|
177
203
|
FLOAT_WIDTH_TEST(double);
|
178
204
|
|
179
205
|
test("Format command with invalid printf format: ");
|
180
|
-
len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",3);
|
206
|
+
len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3);
|
181
207
|
test_cond(len == -1);
|
182
208
|
|
183
209
|
const char *argv[3];
|
@@ -198,6 +224,44 @@ static void test_format_commands(void) {
|
|
198
224
|
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
225
|
len == 4+4+(3+2)+4+(7+2)+4+(3+2));
|
200
226
|
free(cmd);
|
227
|
+
|
228
|
+
sds sds_cmd;
|
229
|
+
|
230
|
+
sds_cmd = sdsempty();
|
231
|
+
test("Format command into sds by passing argc/argv without lengths: ");
|
232
|
+
len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,NULL);
|
233
|
+
test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n",len) == 0 &&
|
234
|
+
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
|
235
|
+
sdsfree(sds_cmd);
|
236
|
+
|
237
|
+
sds_cmd = sdsempty();
|
238
|
+
test("Format command into sds by passing argc/argv with lengths: ");
|
239
|
+
len = redisFormatSdsCommandArgv(&sds_cmd,argc,argv,lens);
|
240
|
+
test_cond(strncmp(sds_cmd,"*3\r\n$3\r\nSET\r\n$7\r\nfoo\0xxx\r\n$3\r\nbar\r\n",len) == 0 &&
|
241
|
+
len == 4+4+(3+2)+4+(7+2)+4+(3+2));
|
242
|
+
sdsfree(sds_cmd);
|
243
|
+
}
|
244
|
+
|
245
|
+
static void test_append_formatted_commands(struct config config) {
|
246
|
+
redisContext *c;
|
247
|
+
redisReply *reply;
|
248
|
+
char *cmd;
|
249
|
+
int len;
|
250
|
+
|
251
|
+
c = connect(config);
|
252
|
+
|
253
|
+
test("Append format command: ");
|
254
|
+
|
255
|
+
len = redisFormatCommand(&cmd, "SET foo bar");
|
256
|
+
|
257
|
+
test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK);
|
258
|
+
|
259
|
+
assert(redisGetReply(c, (void*)&reply) == REDIS_OK);
|
260
|
+
|
261
|
+
free(cmd);
|
262
|
+
freeReplyObject(reply);
|
263
|
+
|
264
|
+
disconnect(c, 0);
|
201
265
|
}
|
202
266
|
|
203
267
|
static void test_reply_reader(void) {
|
@@ -238,6 +302,82 @@ static void test_reply_reader(void) {
|
|
238
302
|
strncasecmp(reader->errstr,"No support for",14) == 0);
|
239
303
|
redisReaderFree(reader);
|
240
304
|
|
305
|
+
test("Correctly parses LLONG_MAX: ");
|
306
|
+
reader = redisReaderCreate();
|
307
|
+
redisReaderFeed(reader, ":9223372036854775807\r\n",22);
|
308
|
+
ret = redisReaderGetReply(reader,&reply);
|
309
|
+
test_cond(ret == REDIS_OK &&
|
310
|
+
((redisReply*)reply)->type == REDIS_REPLY_INTEGER &&
|
311
|
+
((redisReply*)reply)->integer == LLONG_MAX);
|
312
|
+
freeReplyObject(reply);
|
313
|
+
redisReaderFree(reader);
|
314
|
+
|
315
|
+
test("Set error when > LLONG_MAX: ");
|
316
|
+
reader = redisReaderCreate();
|
317
|
+
redisReaderFeed(reader, ":9223372036854775808\r\n",22);
|
318
|
+
ret = redisReaderGetReply(reader,&reply);
|
319
|
+
test_cond(ret == REDIS_ERR &&
|
320
|
+
strcasecmp(reader->errstr,"Bad integer value") == 0);
|
321
|
+
freeReplyObject(reply);
|
322
|
+
redisReaderFree(reader);
|
323
|
+
|
324
|
+
test("Correctly parses LLONG_MIN: ");
|
325
|
+
reader = redisReaderCreate();
|
326
|
+
redisReaderFeed(reader, ":-9223372036854775808\r\n",23);
|
327
|
+
ret = redisReaderGetReply(reader,&reply);
|
328
|
+
test_cond(ret == REDIS_OK &&
|
329
|
+
((redisReply*)reply)->type == REDIS_REPLY_INTEGER &&
|
330
|
+
((redisReply*)reply)->integer == LLONG_MIN);
|
331
|
+
freeReplyObject(reply);
|
332
|
+
redisReaderFree(reader);
|
333
|
+
|
334
|
+
test("Set error when < LLONG_MIN: ");
|
335
|
+
reader = redisReaderCreate();
|
336
|
+
redisReaderFeed(reader, ":-9223372036854775809\r\n",23);
|
337
|
+
ret = redisReaderGetReply(reader,&reply);
|
338
|
+
test_cond(ret == REDIS_ERR &&
|
339
|
+
strcasecmp(reader->errstr,"Bad integer value") == 0);
|
340
|
+
freeReplyObject(reply);
|
341
|
+
redisReaderFree(reader);
|
342
|
+
|
343
|
+
test("Set error when array < -1: ");
|
344
|
+
reader = redisReaderCreate();
|
345
|
+
redisReaderFeed(reader, "*-2\r\n+asdf\r\n",12);
|
346
|
+
ret = redisReaderGetReply(reader,&reply);
|
347
|
+
test_cond(ret == REDIS_ERR &&
|
348
|
+
strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0);
|
349
|
+
freeReplyObject(reply);
|
350
|
+
redisReaderFree(reader);
|
351
|
+
|
352
|
+
test("Set error when bulk < -1: ");
|
353
|
+
reader = redisReaderCreate();
|
354
|
+
redisReaderFeed(reader, "$-2\r\nasdf\r\n",11);
|
355
|
+
ret = redisReaderGetReply(reader,&reply);
|
356
|
+
test_cond(ret == REDIS_ERR &&
|
357
|
+
strcasecmp(reader->errstr,"Bulk string length out of range") == 0);
|
358
|
+
freeReplyObject(reply);
|
359
|
+
redisReaderFree(reader);
|
360
|
+
|
361
|
+
test("Set error when array > INT_MAX: ");
|
362
|
+
reader = redisReaderCreate();
|
363
|
+
redisReaderFeed(reader, "*9223372036854775807\r\n+asdf\r\n",29);
|
364
|
+
ret = redisReaderGetReply(reader,&reply);
|
365
|
+
test_cond(ret == REDIS_ERR &&
|
366
|
+
strcasecmp(reader->errstr,"Multi-bulk length out of range") == 0);
|
367
|
+
freeReplyObject(reply);
|
368
|
+
redisReaderFree(reader);
|
369
|
+
|
370
|
+
#if LLONG_MAX > SIZE_MAX
|
371
|
+
test("Set error when bulk > SIZE_MAX: ");
|
372
|
+
reader = redisReaderCreate();
|
373
|
+
redisReaderFeed(reader, "$9223372036854775807\r\nasdf\r\n",28);
|
374
|
+
ret = redisReaderGetReply(reader,&reply);
|
375
|
+
test_cond(ret == REDIS_ERR &&
|
376
|
+
strcasecmp(reader->errstr,"Bulk string length out of range") == 0);
|
377
|
+
freeReplyObject(reply);
|
378
|
+
redisReaderFree(reader);
|
379
|
+
#endif
|
380
|
+
|
241
381
|
test("Works with NULL functions for reply: ");
|
242
382
|
reader = redisReaderCreate();
|
243
383
|
reader->fn = NULL;
|
@@ -279,14 +419,32 @@ static void test_reply_reader(void) {
|
|
279
419
|
redisReaderFree(reader);
|
280
420
|
}
|
281
421
|
|
422
|
+
static void test_free_null(void) {
|
423
|
+
void *redisCtx = NULL;
|
424
|
+
void *reply = NULL;
|
425
|
+
|
426
|
+
test("Don't fail when redisFree is passed a NULL value: ");
|
427
|
+
redisFree(redisCtx);
|
428
|
+
test_cond(redisCtx == NULL);
|
429
|
+
|
430
|
+
test("Don't fail when freeReplyObject is passed a NULL value: ");
|
431
|
+
freeReplyObject(reply);
|
432
|
+
test_cond(reply == NULL);
|
433
|
+
}
|
434
|
+
|
282
435
|
static void test_blocking_connection_errors(void) {
|
283
436
|
redisContext *c;
|
284
437
|
|
285
438
|
test("Returns error when host cannot be resolved: ");
|
286
|
-
c = redisConnect((char*)"idontexist.
|
439
|
+
c = redisConnect((char*)"idontexist.test", 6379);
|
287
440
|
test_cond(c->err == REDIS_ERR_OTHER &&
|
288
441
|
(strcmp(c->errstr,"Name or service not known") == 0 ||
|
289
|
-
strcmp(c->errstr,"Can't resolve: idontexist.
|
442
|
+
strcmp(c->errstr,"Can't resolve: idontexist.test") == 0 ||
|
443
|
+
strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 ||
|
444
|
+
strcmp(c->errstr,"No address associated with hostname") == 0 ||
|
445
|
+
strcmp(c->errstr,"Temporary failure in name resolution") == 0 ||
|
446
|
+
strcmp(c->errstr,"hostname nor servname provided, or not known") == 0 ||
|
447
|
+
strcmp(c->errstr,"no address associated with name") == 0));
|
290
448
|
redisFree(c);
|
291
449
|
|
292
450
|
test("Returns error when the port is not open: ");
|
@@ -295,7 +453,7 @@ static void test_blocking_connection_errors(void) {
|
|
295
453
|
strcmp(c->errstr,"Connection refused") == 0);
|
296
454
|
redisFree(c);
|
297
455
|
|
298
|
-
test("Returns error when the
|
456
|
+
test("Returns error when the unix_sock socket path doesn't accept connections: ");
|
299
457
|
c = redisConnectUnix((char*)"/tmp/idontexist.sock");
|
300
458
|
test_cond(c->err == REDIS_ERR_IO); /* Don't care about the message... */
|
301
459
|
redisFree(c);
|
@@ -328,7 +486,7 @@ static void test_blocking_connection(struct config config) {
|
|
328
486
|
freeReplyObject(reply);
|
329
487
|
|
330
488
|
test("%%b String interpolation works: ");
|
331
|
-
reply = redisCommand(c,"SET %b %b","foo",3,"hello\x00world",11);
|
489
|
+
reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11);
|
332
490
|
freeReplyObject(reply);
|
333
491
|
reply = redisCommand(c,"GET foo");
|
334
492
|
test_cond(reply->type == REDIS_REPLY_STRING &&
|
@@ -376,7 +534,53 @@ static void test_blocking_connection(struct config config) {
|
|
376
534
|
strcasecmp(reply->element[1]->str,"pong") == 0);
|
377
535
|
freeReplyObject(reply);
|
378
536
|
|
379
|
-
disconnect(c);
|
537
|
+
disconnect(c, 0);
|
538
|
+
}
|
539
|
+
|
540
|
+
static void test_blocking_connection_timeouts(struct config config) {
|
541
|
+
redisContext *c;
|
542
|
+
redisReply *reply;
|
543
|
+
ssize_t s;
|
544
|
+
const char *cmd = "DEBUG SLEEP 3\r\n";
|
545
|
+
struct timeval tv;
|
546
|
+
|
547
|
+
c = connect(config);
|
548
|
+
test("Successfully completes a command when the timeout is not exceeded: ");
|
549
|
+
reply = redisCommand(c,"SET foo fast");
|
550
|
+
freeReplyObject(reply);
|
551
|
+
tv.tv_sec = 0;
|
552
|
+
tv.tv_usec = 10000;
|
553
|
+
redisSetTimeout(c, tv);
|
554
|
+
reply = redisCommand(c, "GET foo");
|
555
|
+
test_cond(reply != NULL && reply->type == REDIS_REPLY_STRING && memcmp(reply->str, "fast", 4) == 0);
|
556
|
+
freeReplyObject(reply);
|
557
|
+
disconnect(c, 0);
|
558
|
+
|
559
|
+
c = connect(config);
|
560
|
+
test("Does not return a reply when the command times out: ");
|
561
|
+
s = write(c->fd, cmd, strlen(cmd));
|
562
|
+
tv.tv_sec = 0;
|
563
|
+
tv.tv_usec = 10000;
|
564
|
+
redisSetTimeout(c, tv);
|
565
|
+
reply = redisCommand(c, "GET foo");
|
566
|
+
test_cond(s > 0 && reply == NULL && c->err == REDIS_ERR_IO && strcmp(c->errstr, "Resource temporarily unavailable") == 0);
|
567
|
+
freeReplyObject(reply);
|
568
|
+
|
569
|
+
test("Reconnect properly reconnects after a timeout: ");
|
570
|
+
redisReconnect(c);
|
571
|
+
reply = redisCommand(c, "PING");
|
572
|
+
test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
|
573
|
+
freeReplyObject(reply);
|
574
|
+
|
575
|
+
test("Reconnect properly uses owned parameters: ");
|
576
|
+
config.tcp.host = "foo";
|
577
|
+
config.unix_sock.path = "foo";
|
578
|
+
redisReconnect(c);
|
579
|
+
reply = redisCommand(c, "PING");
|
580
|
+
test_cond(reply != NULL && reply->type == REDIS_REPLY_STATUS && strcmp(reply->str, "PONG") == 0);
|
581
|
+
freeReplyObject(reply);
|
582
|
+
|
583
|
+
disconnect(c, 0);
|
380
584
|
}
|
381
585
|
|
382
586
|
static void test_blocking_io_errors(struct config config) {
|
@@ -402,7 +606,7 @@ static void test_blocking_io_errors(struct config config) {
|
|
402
606
|
|
403
607
|
test("Returns I/O error when the connection is lost: ");
|
404
608
|
reply = redisCommand(c,"QUIT");
|
405
|
-
if (major
|
609
|
+
if (major > 2 || (major == 2 && minor > 0)) {
|
406
610
|
/* > 2.0 returns OK on QUIT and read() should be issued once more
|
407
611
|
* to know the descriptor is at EOF. */
|
408
612
|
test_cond(strcasecmp(reply->str,"OK") == 0 &&
|
@@ -430,6 +634,30 @@ static void test_blocking_io_errors(struct config config) {
|
|
430
634
|
redisFree(c);
|
431
635
|
}
|
432
636
|
|
637
|
+
static void test_invalid_timeout_errors(struct config config) {
|
638
|
+
redisContext *c;
|
639
|
+
|
640
|
+
test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: ");
|
641
|
+
|
642
|
+
config.tcp.timeout.tv_sec = 0;
|
643
|
+
config.tcp.timeout.tv_usec = 10000001;
|
644
|
+
|
645
|
+
c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
|
646
|
+
|
647
|
+
test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0);
|
648
|
+
redisFree(c);
|
649
|
+
|
650
|
+
test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: ");
|
651
|
+
|
652
|
+
config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1;
|
653
|
+
config.tcp.timeout.tv_usec = 0;
|
654
|
+
|
655
|
+
c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
|
656
|
+
|
657
|
+
test_cond(c->err == REDIS_ERR_IO && strcmp(c->errstr, "Invalid timeout specified") == 0);
|
658
|
+
redisFree(c);
|
659
|
+
}
|
660
|
+
|
433
661
|
static void test_throughput(struct config config) {
|
434
662
|
redisContext *c = connect(config);
|
435
663
|
redisReply **replies;
|
@@ -464,6 +692,17 @@ static void test_throughput(struct config config) {
|
|
464
692
|
free(replies);
|
465
693
|
printf("\t(%dx LRANGE with 500 elements: %.3fs)\n", num, (t2-t1)/1000000.0);
|
466
694
|
|
695
|
+
replies = malloc(sizeof(redisReply*)*num);
|
696
|
+
t1 = usec();
|
697
|
+
for (i = 0; i < num; i++) {
|
698
|
+
replies[i] = redisCommand(c, "INCRBY incrkey %d", 1000000);
|
699
|
+
assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER);
|
700
|
+
}
|
701
|
+
t2 = usec();
|
702
|
+
for (i = 0; i < num; i++) freeReplyObject(replies[i]);
|
703
|
+
free(replies);
|
704
|
+
printf("\t(%dx INCRBY: %.3fs)\n", num, (t2-t1)/1000000.0);
|
705
|
+
|
467
706
|
num = 10000;
|
468
707
|
replies = malloc(sizeof(redisReply*)*num);
|
469
708
|
for (i = 0; i < num; i++)
|
@@ -492,7 +731,20 @@ static void test_throughput(struct config config) {
|
|
492
731
|
free(replies);
|
493
732
|
printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
|
494
733
|
|
495
|
-
|
734
|
+
replies = malloc(sizeof(redisReply*)*num);
|
735
|
+
for (i = 0; i < num; i++)
|
736
|
+
redisAppendCommand(c,"INCRBY incrkey %d", 1000000);
|
737
|
+
t1 = usec();
|
738
|
+
for (i = 0; i < num; i++) {
|
739
|
+
assert(redisGetReply(c, (void*)&replies[i]) == REDIS_OK);
|
740
|
+
assert(replies[i] != NULL && replies[i]->type == REDIS_REPLY_INTEGER);
|
741
|
+
}
|
742
|
+
t2 = usec();
|
743
|
+
for (i = 0; i < num; i++) freeReplyObject(replies[i]);
|
744
|
+
free(replies);
|
745
|
+
printf("\t(%dx INCRBY (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
|
746
|
+
|
747
|
+
disconnect(c, 0);
|
496
748
|
}
|
497
749
|
|
498
750
|
// static long __test_callback_flags = 0;
|
@@ -600,11 +852,12 @@ int main(int argc, char **argv) {
|
|
600
852
|
.host = "127.0.0.1",
|
601
853
|
.port = 6379
|
602
854
|
},
|
603
|
-
.
|
855
|
+
.unix_sock = {
|
604
856
|
.path = "/tmp/redis.sock"
|
605
857
|
}
|
606
858
|
};
|
607
859
|
int throughput = 1;
|
860
|
+
int test_inherit_fd = 1;
|
608
861
|
|
609
862
|
/* Ignore broken pipe signal (for I/O error tests). */
|
610
863
|
signal(SIGPIPE, SIG_IGN);
|
@@ -620,9 +873,11 @@ int main(int argc, char **argv) {
|
|
620
873
|
cfg.tcp.port = atoi(argv[0]);
|
621
874
|
} else if (argc >= 2 && !strcmp(argv[0],"-s")) {
|
622
875
|
argv++; argc--;
|
623
|
-
cfg.
|
876
|
+
cfg.unix_sock.path = argv[0];
|
624
877
|
} else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) {
|
625
878
|
throughput = 0;
|
879
|
+
} else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) {
|
880
|
+
test_inherit_fd = 0;
|
626
881
|
} else {
|
627
882
|
fprintf(stderr, "Invalid argument: %s\n", argv[0]);
|
628
883
|
exit(1);
|
@@ -633,19 +888,31 @@ int main(int argc, char **argv) {
|
|
633
888
|
test_format_commands();
|
634
889
|
test_reply_reader();
|
635
890
|
test_blocking_connection_errors();
|
891
|
+
test_free_null();
|
636
892
|
|
637
893
|
printf("\nTesting against TCP connection (%s:%d):\n", cfg.tcp.host, cfg.tcp.port);
|
638
894
|
cfg.type = CONN_TCP;
|
639
895
|
test_blocking_connection(cfg);
|
896
|
+
test_blocking_connection_timeouts(cfg);
|
640
897
|
test_blocking_io_errors(cfg);
|
898
|
+
test_invalid_timeout_errors(cfg);
|
899
|
+
test_append_formatted_commands(cfg);
|
641
900
|
if (throughput) test_throughput(cfg);
|
642
901
|
|
643
|
-
printf("\nTesting against Unix socket connection (%s):\n", cfg.
|
902
|
+
printf("\nTesting against Unix socket connection (%s):\n", cfg.unix_sock.path);
|
644
903
|
cfg.type = CONN_UNIX;
|
645
904
|
test_blocking_connection(cfg);
|
905
|
+
test_blocking_connection_timeouts(cfg);
|
646
906
|
test_blocking_io_errors(cfg);
|
647
907
|
if (throughput) test_throughput(cfg);
|
648
908
|
|
909
|
+
if (test_inherit_fd) {
|
910
|
+
printf("\nTesting against inherited fd (%s):\n", cfg.unix_sock.path);
|
911
|
+
cfg.type = CONN_FD;
|
912
|
+
test_blocking_connection(cfg);
|
913
|
+
}
|
914
|
+
|
915
|
+
|
649
916
|
if (fails) {
|
650
917
|
printf("*** %d TESTS FAILED ***\n", fails);
|
651
918
|
return 1;
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#ifndef _WIN32_HELPER_INCLUDE
|
2
|
+
#define _WIN32_HELPER_INCLUDE
|
3
|
+
#ifdef _MSC_VER
|
4
|
+
|
5
|
+
#ifndef inline
|
6
|
+
#define inline __inline
|
7
|
+
#endif
|
8
|
+
|
9
|
+
#ifndef va_copy
|
10
|
+
#define va_copy(d,s) ((d) = (s))
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#ifndef snprintf
|
14
|
+
#define snprintf c99_snprintf
|
15
|
+
|
16
|
+
__inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
|
17
|
+
{
|
18
|
+
int count = -1;
|
19
|
+
|
20
|
+
if (size != 0)
|
21
|
+
count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
|
22
|
+
if (count == -1)
|
23
|
+
count = _vscprintf(format, ap);
|
24
|
+
|
25
|
+
return count;
|
26
|
+
}
|
27
|
+
|
28
|
+
__inline int c99_snprintf(char* str, size_t size, const char* format, ...)
|
29
|
+
{
|
30
|
+
int count;
|
31
|
+
va_list ap;
|
32
|
+
|
33
|
+
va_start(ap, format);
|
34
|
+
count = c99_vsnprintf(str, size, format, ap);
|
35
|
+
va_end(ap);
|
36
|
+
|
37
|
+
return count;
|
38
|
+
}
|
39
|
+
#endif
|
40
|
+
|
41
|
+
#endif
|
42
|
+
#endif
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hiredis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pieter Noordhuis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -28,16 +28,30 @@ dependencies:
|
|
28
28
|
name: rake-compiler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 0.7.1
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.7.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 5.5.1
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 5.5.1
|
41
55
|
description: Ruby wrapper for hiredis (protocol serialization/deserialization and
|
42
56
|
blocking I/O)
|
43
57
|
email:
|
@@ -47,38 +61,42 @@ extensions:
|
|
47
61
|
- ext/hiredis_ext/extconf.rb
|
48
62
|
extra_rdoc_files: []
|
49
63
|
files:
|
50
|
-
-
|
64
|
+
- COPYING
|
65
|
+
- Rakefile
|
51
66
|
- ext/hiredis_ext/connection.c
|
67
|
+
- ext/hiredis_ext/extconf.rb
|
52
68
|
- ext/hiredis_ext/hiredis_ext.c
|
53
|
-
- ext/hiredis_ext/reader.c
|
54
69
|
- ext/hiredis_ext/hiredis_ext.h
|
55
|
-
-
|
56
|
-
-
|
57
|
-
- vendor/hiredis/hiredis.c
|
58
|
-
- vendor/hiredis/net.c
|
59
|
-
- vendor/hiredis/sds.c
|
60
|
-
- vendor/hiredis/test.c
|
61
|
-
- vendor/hiredis/async.h
|
62
|
-
- vendor/hiredis/dict.h
|
63
|
-
- vendor/hiredis/fmacros.h
|
64
|
-
- vendor/hiredis/hiredis.h
|
65
|
-
- vendor/hiredis/net.h
|
66
|
-
- vendor/hiredis/sds.h
|
67
|
-
- vendor/hiredis/COPYING
|
68
|
-
- vendor/hiredis/Makefile
|
70
|
+
- ext/hiredis_ext/reader.c
|
71
|
+
- lib/hiredis.rb
|
69
72
|
- lib/hiredis/connection.rb
|
70
|
-
- lib/hiredis/errors.rb
|
71
73
|
- lib/hiredis/ext/connection.rb
|
72
74
|
- lib/hiredis/ext/reader.rb
|
73
75
|
- lib/hiredis/reader.rb
|
74
76
|
- lib/hiredis/ruby/connection.rb
|
75
77
|
- lib/hiredis/ruby/reader.rb
|
76
78
|
- lib/hiredis/version.rb
|
77
|
-
-
|
78
|
-
-
|
79
|
-
-
|
79
|
+
- vendor/hiredis/COPYING
|
80
|
+
- vendor/hiredis/Makefile
|
81
|
+
- vendor/hiredis/async.c
|
82
|
+
- vendor/hiredis/async.h
|
83
|
+
- vendor/hiredis/dict.c
|
84
|
+
- vendor/hiredis/dict.h
|
85
|
+
- vendor/hiredis/fmacros.h
|
86
|
+
- vendor/hiredis/hiredis.c
|
87
|
+
- vendor/hiredis/hiredis.h
|
88
|
+
- vendor/hiredis/net.c
|
89
|
+
- vendor/hiredis/net.h
|
90
|
+
- vendor/hiredis/read.c
|
91
|
+
- vendor/hiredis/read.h
|
92
|
+
- vendor/hiredis/sds.c
|
93
|
+
- vendor/hiredis/sds.h
|
94
|
+
- vendor/hiredis/sdsalloc.h
|
95
|
+
- vendor/hiredis/test.c
|
96
|
+
- vendor/hiredis/win32.h
|
80
97
|
homepage: http://github.com/redis/hiredis-rb
|
81
|
-
licenses:
|
98
|
+
licenses:
|
99
|
+
- BSD-3-Clause
|
82
100
|
metadata: {}
|
83
101
|
post_install_message:
|
84
102
|
rdoc_options: []
|
@@ -86,17 +104,17 @@ require_paths:
|
|
86
104
|
- lib
|
87
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
88
106
|
requirements:
|
89
|
-
- -
|
107
|
+
- - ">="
|
90
108
|
- !ruby/object:Gem::Version
|
91
109
|
version: '0'
|
92
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
111
|
requirements:
|
94
|
-
- -
|
112
|
+
- - ">="
|
95
113
|
- !ruby/object:Gem::Version
|
96
114
|
version: '0'
|
97
115
|
requirements: []
|
98
116
|
rubyforge_project:
|
99
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.7.6
|
100
118
|
signing_key:
|
101
119
|
specification_version: 4
|
102
120
|
summary: Ruby wrapper for hiredis (protocol serialization/deserialization and blocking
|