test: don't use bdev_svc application in this test

bdev_svc require system setup (like bdevs, nvme etc.) otherwise it
writes tons of  errors. Instead just start RPC server on separate thread
and connect to it.

Change-Id: I99ee58cbccbf982d70155c8ecf0fd7f860b3b6ab
Signed-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-on: https://review.gerrithub.io/430316
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
Pawel Wodkowski 2018-10-22 11:27:09 +02:00 committed by Jim Harris
parent 2f557958d0
commit e6c30818e3
3 changed files with 166 additions and 31 deletions

View File

@ -40,7 +40,7 @@ APP = rpc_client_test
C_SRCS := rpc_client_test.c
SPDK_LIB_LIST = jsonrpc json log util
SPDK_LIB_LIST = jsonrpc json rpc log util
LIBS += $(SPDK_LIB_LINKER_ARGS) $(ENV_LINKER_ARGS)

View File

@ -7,30 +7,8 @@ set -e
source $rootdir/test/common/autotest_common.sh
function rpc_client_test() {
if [ $(uname -s) = Linux ]; then
local conf=$rootdir/test/bdev/bdev.conf.in
if [ ! -e $conf ]; then
return 1
fi
$rootdir/test/app/bdev_svc/bdev_svc -i 0 -c ${conf} &
svc_pid=$!
echo "Process bdev_svc pid: $svc_pid"
waitforlisten $svc_pid
trap "killprocess $svc_pid" SIGINT SIGTERM EXIT
$rootdir/test/rpc_client/rpc_client_test
killprocess $svc_pid
fi
return 0
}
timing_enter rpc_client
rpc_client_test
$rootdir/test/rpc_client/rpc_client_test
timing_exit rpc_client
trap - SIGINT SIGTERM EXIT

View File

@ -34,8 +34,12 @@
#include "spdk/stdinc.h"
#include "spdk/event.h"
#include "spdk/jsonrpc.h"
#include "spdk/util.h"
#include "spdk/rpc.h"
#define RPC_MAX_METHODS 200
#define JOIN_TIMEOUT_S 1
static const char *g_rpcsock_addr = SPDK_DEFAULT_RPC_ADDR;
static int g_addr_family = AF_UNIX;
@ -73,13 +77,17 @@ spdk_jsonrpc_client_check_rpc_method(struct spdk_jsonrpc_client *client, char *m
spdk_jsonrpc_end_request(request, w);
spdk_jsonrpc_client_send_request(client, request);
rc = spdk_jsonrpc_client_recv_response(client);
if (rc) {
do {
rc = spdk_jsonrpc_client_recv_response(client);
} while (rc == -EAGAIN || rc == -ENOTCONN);
if (rc != 0) {
goto out;
}
json_resp = spdk_jsonrpc_client_get_response(client);
if (json_resp == NULL) {
SPDK_ERRLOG("spdk_jsonrpc_client_get_response() failed\n");
rc = -errno;
goto out;
@ -87,6 +95,7 @@ spdk_jsonrpc_client_check_rpc_method(struct spdk_jsonrpc_client *client, char *m
/* Check for error response */
if (json_resp->error != NULL) {
SPDK_ERRLOG("Unexpected error response\n");
rc = -1;
goto out;
}
@ -95,6 +104,7 @@ spdk_jsonrpc_client_check_rpc_method(struct spdk_jsonrpc_client *client, char *m
rc = get_jsonrpc_method_json_parser(&resp, json_resp->result);
if (rc) {
SPDK_ERRLOG("get_jsonrpc_method_json_parser() failed\n");
goto out;
}
@ -106,6 +116,7 @@ spdk_jsonrpc_client_check_rpc_method(struct spdk_jsonrpc_client *client, char *m
}
rc = -1;
SPDK_ERRLOG("Method '%s' not found in response\n", method_name);
out:
for (i = 0; i < (int)resp.method_num; i++) {
@ -117,20 +128,166 @@ out:
return rc;
}
int main(int argc, char **argv)
static void
rpc_test_method_startup(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
{
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"rpc_test_method_startup(): Method body not implemented");
}
SPDK_RPC_REGISTER("test_method_startup", rpc_test_method_startup, SPDK_RPC_STARTUP)
static void
rpc_test_method_runtime(struct spdk_jsonrpc_request *request, const struct spdk_json_val *params)
{
spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
"rpc_test_method_runtime(): Method body not implemented");
}
SPDK_RPC_REGISTER("test_method_runtime", rpc_test_method_runtime, SPDK_RPC_RUNTIME)
/* Helper function */
static int
_sem_timedwait(sem_t *sem, __time_t sec)
{
struct timespec timeout;
clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += sec;
return sem_timedwait(sem, &timeout);
}
volatile int g_rpc_server_th_stop;
static sem_t g_rpc_server_th_listening;
static sem_t g_rpc_server_th_done;
static void *
rpc_server_th(void *arg)
{
struct spdk_jsonrpc_client *client;
int rc;
rc = spdk_rpc_listen(g_rpcsock_addr);
if (rc) {
fprintf(stderr, "spdk_rpc_listen() failed: %d\n", rc);
goto out;
}
sem_post(&g_rpc_server_th_listening);
while (!g_rpc_server_th_stop) {
spdk_rpc_accept();
usleep(50);
}
spdk_rpc_close();
out:
sem_post(&g_rpc_server_th_done);
return (void *)(intptr_t)rc;
}
static sem_t g_rpc_client_th_done;
static void *
rpc_client_th(void *arg)
{
struct spdk_jsonrpc_client *client = NULL;
char *method_name = "get_rpc_methods";
int rc;
rc = _sem_timedwait(&g_rpc_server_th_listening, 2);
if (rc == -1) {
fprintf(stderr, "Timeout waiting for server thread to start listening: %d\n", errno);
goto out;
}
client = spdk_jsonrpc_client_connect(g_rpcsock_addr, g_addr_family);
if (!client) {
return EXIT_FAILURE;
fprintf(stderr, "spdk_jsonrpc_client_connect() failed: %d\n", errno);
rc = -1;
goto out;
}
rc = spdk_jsonrpc_client_check_rpc_method(client, method_name);
if (rc) {
fprintf(stderr, "spdk_jsonrpc_client_check_rpc_method() failed: %d\n", errno);
goto out;
}
spdk_jsonrpc_client_close(client);
out:
if (client) {
spdk_jsonrpc_client_close(client);
}
return rc ? EXIT_FAILURE : 0;
sem_post(&g_rpc_client_th_done);
return (void *)(intptr_t)rc;
}
int main(int argc, char **argv)
{
pthread_t srv_tid, client_tid;
int srv_tid_valid;
int client_tid_valid = -1;
int th_rc = INT_MIN;
int rc = 0, err_cnt = 0;
sem_init(&g_rpc_server_th_listening, 0, 0);
sem_init(&g_rpc_server_th_done, 0, 0);
sem_init(&g_rpc_client_th_done, 0, 0);
srv_tid_valid = pthread_create(&srv_tid, NULL, rpc_server_th, NULL);
if (srv_tid_valid != 0) {
fprintf(stderr, "pthread_create() failed to create server thread: %d\n", srv_tid_valid);
goto out;
}
client_tid_valid = pthread_create(&client_tid, NULL, rpc_client_th, NULL);
if (client_tid_valid != 0) {
fprintf(stderr, "pthread_create(): failed to create client thread: %d\n", client_tid_valid);
goto out;
}
out:
if (client_tid_valid == 0) {
rc = _sem_timedwait(&g_rpc_client_th_done, JOIN_TIMEOUT_S);
if (rc) {
fprintf(stderr, "failed to join client thread (rc: %d)\n", rc);
err_cnt++;
}
rc = pthread_join(client_tid, (void **)&th_rc);
if (rc) {
fprintf(stderr, "pthread_join() on cliennt thread failed (rc: %d)\n", rc);
err_cnt++;
} else if (th_rc) {
fprintf(stderr, "cliennt thread failed reported failure(thread rc: %d)\n", th_rc);
err_cnt++;
}
}
g_rpc_server_th_stop = 1;
if (srv_tid_valid == 0) {
rc = _sem_timedwait(&g_rpc_server_th_done, JOIN_TIMEOUT_S);
if (rc) {
fprintf(stderr, "server thread failed to exit in %d sec: (rc: %d)\n", JOIN_TIMEOUT_S, rc);
err_cnt++;
}
rc = pthread_join(srv_tid, (void **)&th_rc);
if (rc) {
fprintf(stderr, "pthread_join() on cliennt thread failed (rc: %d)\n", rc);
err_cnt++;
} else if (th_rc) {
fprintf(stderr, "cliennt thread failed reported failure(thread rc: %d)\n", th_rc);
err_cnt++;
}
}
sem_destroy(&g_rpc_server_th_listening);
sem_destroy(&g_rpc_server_th_done);
sem_destroy(&g_rpc_client_th_done);
fprintf(stderr, "%s\n", err_cnt == 0 ? "OK" : "FAILED");
return err_cnt ? EXIT_FAILURE : 0;
}