Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
4b901d44
Commit
4b901d44
authored
Apr 20, 2021
by
Kristján Valur Jónsson
Browse files
Initial async tests
parent
31c91408
Changes
1
Hide whitespace changes
Inline
Side-by-side
test.c
View file @
4b901d44
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,7 @@
#include "hiredis.h"
#include "hiredis.h"
#include "async.h"
#include "async.h"
#include "adapters/poll.h"
#ifdef HIREDIS_TEST_SSL
#ifdef HIREDIS_TEST_SSL
#include "hiredis_ssl.h"
#include "hiredis_ssl.h"
#endif
#endif
...
@@ -1898,6 +1899,174 @@ static void test_monitor(struct config config) {
...
@@ -1898,6 +1899,174 @@ static void test_monitor(struct config config) {
}
}
#endif
/* HIREDIS_TEST_ASYNC */
#endif
/* HIREDIS_TEST_ASYNC */
/* tests for async api using polling adapter, requires no extra libraries*/
/* a static context for the async tests */
typedef
enum
astest_no
{
ASTEST_CONNECT
=
0
,
ASTEST_CONN_TIMEOUT
,
ASTEST_PINGPONG
}
astest_no
;
struct
_astest
{
redisAsyncContext
*
ac
;
astest_no
testno
;
int
counter
;
int
connects
;
int
connect_status
;
int
disconnects
;
int
disconnect_status
;
int
connected
;
int
err
;
char
errstr
[
256
];
};
static
struct
_astest
astest
;
static
void
asCleanup
(
void
*
data
)
{
struct
_astest
*
t
=
(
struct
_astest
*
)
data
;
t
->
ac
=
NULL
;
}
static
void
connectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
struct
_astest
*
t
=
(
struct
_astest
*
)
c
->
data
;
assert
(
t
==
&
astest
);
assert
(
t
->
connects
==
0
);
t
->
err
=
c
->
err
;
strcpy
(
t
->
errstr
,
c
->
errstr
);
t
->
connects
++
;
t
->
connect_status
=
status
;
t
->
connected
=
status
==
REDIS_OK
?
1
:
-
1
;
}
static
void
disconnectCallback
(
const
redisAsyncContext
*
c
,
int
status
)
{
assert
(
c
->
data
==
(
void
*
)
&
astest
);
assert
(
astest
.
disconnects
==
0
);
astest
.
err
=
c
->
err
;
strcpy
(
astest
.
errstr
,
c
->
errstr
);
astest
.
disconnects
++
;
astest
.
disconnect_status
=
status
;
astest
.
connected
=
0
;
}
static
void
commandCallback
(
struct
redisAsyncContext
*
ac
,
void
*
_reply
,
void
*
_privdata
)
{
redisReply
*
reply
=
(
redisReply
*
)
_reply
;
struct
_astest
*
t
=
(
struct
_astest
*
)
ac
->
data
;
assert
(
t
==
&
astest
);
(
void
)
_privdata
;
t
->
err
=
ac
->
err
;
strcpy
(
t
->
errstr
,
ac
->
errstr
);
if
(
t
->
testno
==
ASTEST_PINGPONG
)
{
test_cond
(
reply
!=
NULL
&&
reply
->
type
==
REDIS_REPLY_STATUS
&&
strcmp
(
reply
->
str
,
"PONG"
)
==
0
);
redisAsyncFree
(
ac
);
}
}
static
redisAsyncContext
*
do_aconnect
(
struct
config
config
,
astest_no
testno
)
{
redisOptions
options
=
{
0
};
memset
(
&
astest
,
0
,
sizeof
(
astest
));
astest
.
testno
=
testno
;
astest
.
connect_status
=
astest
.
disconnect_status
=
-
2
;
if
(
config
.
type
==
CONN_TCP
)
{
options
.
type
=
REDIS_CONN_TCP
;
options
.
connect_timeout
=
&
config
.
tcp
.
timeout
;
REDIS_OPTIONS_SET_TCP
(
&
options
,
config
.
tcp
.
host
,
config
.
tcp
.
port
);
}
else
if
(
config
.
type
==
CONN_SSL
)
{
options
.
type
=
REDIS_CONN_TCP
;
options
.
connect_timeout
=
&
config
.
tcp
.
timeout
;
REDIS_OPTIONS_SET_TCP
(
&
options
,
config
.
ssl
.
host
,
config
.
ssl
.
port
);
}
else
if
(
config
.
type
==
CONN_UNIX
)
{
options
.
type
=
REDIS_CONN_UNIX
;
options
.
endpoint
.
unix_socket
=
config
.
unix_sock
.
path
;
}
else
if
(
config
.
type
==
CONN_FD
)
{
options
.
type
=
REDIS_CONN_USERFD
;
/* Create a dummy connection just to get an fd to inherit */
redisContext
*
dummy_ctx
=
redisConnectUnix
(
config
.
unix_sock
.
path
);
if
(
dummy_ctx
)
{
redisFD
fd
=
disconnect
(
dummy_ctx
,
1
);
printf
(
"Connecting to inherited fd %d
\n
"
,
(
int
)
fd
);
options
.
endpoint
.
fd
=
fd
;
}
}
redisAsyncContext
*
c
=
redisAsyncConnectWithOptions
(
&
options
);
assert
(
c
);
astest
.
ac
=
c
;
c
->
data
=
&
astest
;
c
->
dataCleanup
=
asCleanup
;
redisPollAttach
(
c
);
redisAsyncSetConnectCallback
(
c
,
connectCallback
);
redisAsyncSetDisconnectCallback
(
c
,
disconnectCallback
);
return
c
;
}
static
void
as_printerr
(
void
)
{
printf
(
"Async err %d : %s
\n
"
,
astest
.
err
,
astest
.
errstr
);
}
#define ASASSERT(e) do { \
if (!(e)) \
as_printerr(); \
assert(e); \
} while (0);
static
void
test_async_polling
(
struct
config
config
)
{
int
status
;
redisAsyncContext
*
c
;
struct
config
defaultconfig
=
config
;
test
(
"Async connect: "
);
c
=
do_aconnect
(
config
,
ASTEST_CONNECT
);
assert
(
c
);
while
(
astest
.
connected
==
0
)
redisPollTick
(
c
,
0
.
1
);
assert
(
astest
.
connects
==
1
);
ASASSERT
(
astest
.
connect_status
==
REDIS_OK
);
assert
(
astest
.
disconnects
==
0
);
test_cond
(
astest
.
connected
==
1
);
test
(
"Async free after connect: "
);
assert
(
astest
.
ac
!=
NULL
);
redisAsyncFree
(
c
);
assert
(
astest
.
disconnects
==
1
);
assert
(
astest
.
ac
==
NULL
);
test_cond
(
astest
.
disconnect_status
==
REDIS_OK
);
if
(
config
.
type
==
CONN_TCP
||
config
.
type
==
CONN_SSL
)
{
/* timeout can only be simulated with network */
test
(
"Async connect timeout: "
);
config
.
tcp
.
host
=
"192.168.254.254"
;
/* blackhole ip */
config
.
tcp
.
timeout
.
tv_usec
=
100000
;
c
=
do_aconnect
(
config
,
ASTEST_CONN_TIMEOUT
);
assert
(
c
);
assert
(
c
->
err
==
0
);
while
(
astest
.
connected
==
0
)
redisPollTick
(
c
,
0
.
1
);
assert
(
astest
.
connected
==
-
1
);
/*
* freeing should not be done, clearing should have happened.
*redisAsyncFree(c);
*/
assert
(
astest
.
ac
==
NULL
);
test_cond
(
astest
.
connect_status
==
REDIS_ERR
);
config
=
defaultconfig
;
}
/* Test a ping/pong after connection */
test
(
"Async PING/PONG: "
);
c
=
do_aconnect
(
config
,
ASTEST_PINGPONG
);
while
(
astest
.
connected
==
0
)
redisPollTick
(
c
,
0
.
1
);
status
=
redisAsyncCommand
(
c
,
commandCallback
,
NULL
,
"PING"
);
assert
(
status
==
REDIS_OK
);
while
(
astest
.
ac
)
redisPollTick
(
c
,
0
.
1
);
config
=
defaultconfig
;
}
int
main
(
int
argc
,
char
**
argv
)
{
int
main
(
int
argc
,
char
**
argv
)
{
struct
config
cfg
=
{
struct
config
cfg
=
{
.
tcp
=
{
.
tcp
=
{
...
@@ -2017,6 +2186,7 @@ int main(int argc, char **argv) {
...
@@ -2017,6 +2186,7 @@ int main(int argc, char **argv) {
#endif
#endif
#ifdef HIREDIS_TEST_ASYNC
#ifdef HIREDIS_TEST_ASYNC
cfg
.
type
=
CONN_TCP
;
printf
(
"
\n
Testing asynchronous API against TCP connection (%s:%d):
\n
"
,
cfg
.
tcp
.
host
,
cfg
.
tcp
.
port
);
printf
(
"
\n
Testing asynchronous API against TCP connection (%s:%d):
\n
"
,
cfg
.
tcp
.
host
,
cfg
.
tcp
.
port
);
cfg
.
type
=
CONN_TCP
;
cfg
.
type
=
CONN_TCP
;
...
@@ -2034,6 +2204,15 @@ int main(int argc, char **argv) {
...
@@ -2034,6 +2204,15 @@ int main(int argc, char **argv) {
}
}
#endif
/* HIREDIS_TEST_ASYNC */
#endif
/* HIREDIS_TEST_ASYNC */
cfg
.
type
=
CONN_TCP
;
printf
(
"
\n
Testing asynchronous API using polling_adapter TCP (%s:%d):
\n
"
,
cfg
.
tcp
.
host
,
cfg
.
tcp
.
port
);
test_async_polling
(
cfg
);
if
(
test_unix_socket
)
{
cfg
.
type
=
CONN_UNIX
;
printf
(
"
\n
Testing asynchronous API using polling_adapter UNIX (%s):
\n
"
,
cfg
.
unix_sock
.
path
);
test_async_polling
(
cfg
);
}
if
(
test_inherit_fd
)
{
if
(
test_inherit_fd
)
{
printf
(
"
\n
Testing against inherited fd (%s): "
,
cfg
.
unix_sock
.
path
);
printf
(
"
\n
Testing against inherited fd (%s): "
,
cfg
.
unix_sock
.
path
);
if
(
test_unix_socket
)
{
if
(
test_unix_socket
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment