VSOCK: extract utility functions from vsock_diag_test.c
Move useful functions into a separate file in preparation for more vsock test programs. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Stefano Garzarella <sgarzare@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
ce1c7f84e2
Коммит
df7e0e0d23
|
@ -1,7 +1,7 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
all: test
|
all: test
|
||||||
test: vsock_diag_test
|
test: vsock_diag_test
|
||||||
vsock_diag_test: vsock_diag_test.o timeout.o control.o
|
vsock_diag_test: vsock_diag_test.o timeout.o control.o util.o
|
||||||
|
|
||||||
CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE
|
CFLAGS += -g -O2 -Werror -Wall -I. -I../../include -I../../../usr/include -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE -D_GNU_SOURCE
|
||||||
.PHONY: all test clean
|
.PHONY: all test clean
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* vsock test utilities
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Author: Stefan Hajnoczi <stefanha@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "timeout.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/* Install signal handlers */
|
||||||
|
void init_signals(void)
|
||||||
|
{
|
||||||
|
struct sigaction act = {
|
||||||
|
.sa_handler = sigalrm,
|
||||||
|
};
|
||||||
|
|
||||||
|
sigaction(SIGALRM, &act, NULL);
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse a CID in string representation */
|
||||||
|
unsigned int parse_cid(const char *str)
|
||||||
|
{
|
||||||
|
char *endptr = NULL;
|
||||||
|
unsigned long n;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
n = strtoul(str, &endptr, 10);
|
||||||
|
if (errno || *endptr != '\0') {
|
||||||
|
fprintf(stderr, "malformed CID \"%s\"\n", str);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run test cases. The program terminates if a failure occurs. */
|
||||||
|
void run_tests(const struct test_case *test_cases,
|
||||||
|
const struct test_opts *opts)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; test_cases[i].name; i++) {
|
||||||
|
void (*run)(const struct test_opts *opts);
|
||||||
|
|
||||||
|
printf("%s...", test_cases[i].name);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (opts->mode == TEST_MODE_CLIENT)
|
||||||
|
run = test_cases[i].run_client;
|
||||||
|
else
|
||||||
|
run = test_cases[i].run_server;
|
||||||
|
|
||||||
|
if (run)
|
||||||
|
run(opts);
|
||||||
|
|
||||||
|
printf("ok\n");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#ifndef UTIL_H
|
||||||
|
#define UTIL_H
|
||||||
|
|
||||||
|
/* Tests can either run as the client or the server */
|
||||||
|
enum test_mode {
|
||||||
|
TEST_MODE_UNSET,
|
||||||
|
TEST_MODE_CLIENT,
|
||||||
|
TEST_MODE_SERVER
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Test runner options */
|
||||||
|
struct test_opts {
|
||||||
|
enum test_mode mode;
|
||||||
|
unsigned int peer_cid;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A test case definition. Test functions must print failures to stderr and
|
||||||
|
* terminate with exit(EXIT_FAILURE).
|
||||||
|
*/
|
||||||
|
struct test_case {
|
||||||
|
const char *name; /* human-readable name */
|
||||||
|
|
||||||
|
/* Called when test mode is TEST_MODE_CLIENT */
|
||||||
|
void (*run_client)(const struct test_opts *opts);
|
||||||
|
|
||||||
|
/* Called when test mode is TEST_MODE_SERVER */
|
||||||
|
void (*run_server)(const struct test_opts *opts);
|
||||||
|
};
|
||||||
|
|
||||||
|
void init_signals(void);
|
||||||
|
unsigned int parse_cid(const char *str);
|
||||||
|
void run_tests(const struct test_case *test_cases,
|
||||||
|
const struct test_opts *opts);
|
||||||
|
|
||||||
|
#endif /* UTIL_H */
|
|
@ -9,12 +9,10 @@
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -28,12 +26,7 @@
|
||||||
|
|
||||||
#include "timeout.h"
|
#include "timeout.h"
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
|
#include "util.h"
|
||||||
enum test_mode {
|
|
||||||
TEST_MODE_UNSET,
|
|
||||||
TEST_MODE_CLIENT,
|
|
||||||
TEST_MODE_SERVER
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Per-socket status */
|
/* Per-socket status */
|
||||||
struct vsock_stat {
|
struct vsock_stat {
|
||||||
|
@ -334,7 +327,7 @@ static void free_sock_stat(struct list_head *sockets)
|
||||||
free(st);
|
free(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_no_sockets(unsigned int peer_cid)
|
static void test_no_sockets(const struct test_opts *opts)
|
||||||
{
|
{
|
||||||
LIST_HEAD(sockets);
|
LIST_HEAD(sockets);
|
||||||
|
|
||||||
|
@ -345,7 +338,7 @@ static void test_no_sockets(unsigned int peer_cid)
|
||||||
free_sock_stat(&sockets);
|
free_sock_stat(&sockets);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_listen_socket_server(unsigned int peer_cid)
|
static void test_listen_socket_server(const struct test_opts *opts)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
|
@ -383,7 +376,7 @@ static void test_listen_socket_server(unsigned int peer_cid)
|
||||||
free_sock_stat(&sockets);
|
free_sock_stat(&sockets);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_connect_client(unsigned int peer_cid)
|
static void test_connect_client(const struct test_opts *opts)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
|
@ -392,7 +385,7 @@ static void test_connect_client(unsigned int peer_cid)
|
||||||
.svm = {
|
.svm = {
|
||||||
.svm_family = AF_VSOCK,
|
.svm_family = AF_VSOCK,
|
||||||
.svm_port = 1234,
|
.svm_port = 1234,
|
||||||
.svm_cid = peer_cid,
|
.svm_cid = opts->peer_cid,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
int fd;
|
int fd;
|
||||||
|
@ -429,7 +422,7 @@ static void test_connect_client(unsigned int peer_cid)
|
||||||
free_sock_stat(&sockets);
|
free_sock_stat(&sockets);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_connect_server(unsigned int peer_cid)
|
static void test_connect_server(const struct test_opts *opts)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
|
@ -481,9 +474,9 @@ static void test_connect_server(unsigned int peer_cid)
|
||||||
clientaddr.sa.sa_family);
|
clientaddr.sa.sa_family);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (clientaddr.svm.svm_cid != peer_cid) {
|
if (clientaddr.svm.svm_cid != opts->peer_cid) {
|
||||||
fprintf(stderr, "expected peer CID %u from accept(2), got %u\n",
|
fprintf(stderr, "expected peer CID %u from accept(2), got %u\n",
|
||||||
peer_cid, clientaddr.svm.svm_cid);
|
opts->peer_cid, clientaddr.svm.svm_cid);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,11 +495,7 @@ static void test_connect_server(unsigned int peer_cid)
|
||||||
free_sock_stat(&sockets);
|
free_sock_stat(&sockets);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct {
|
static struct test_case test_cases[] = {
|
||||||
const char *name;
|
|
||||||
void (*run_client)(unsigned int peer_cid);
|
|
||||||
void (*run_server)(unsigned int peer_cid);
|
|
||||||
} test_cases[] = {
|
|
||||||
{
|
{
|
||||||
.name = "No sockets",
|
.name = "No sockets",
|
||||||
.run_server = test_no_sockets,
|
.run_server = test_no_sockets,
|
||||||
|
@ -523,30 +512,6 @@ static struct {
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void init_signals(void)
|
|
||||||
{
|
|
||||||
struct sigaction act = {
|
|
||||||
.sa_handler = sigalrm,
|
|
||||||
};
|
|
||||||
|
|
||||||
sigaction(SIGALRM, &act, NULL);
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int parse_cid(const char *str)
|
|
||||||
{
|
|
||||||
char *endptr = NULL;
|
|
||||||
unsigned long int n;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
n = strtoul(str, &endptr, 10);
|
|
||||||
if (errno || *endptr != '\0') {
|
|
||||||
fprintf(stderr, "malformed CID \"%s\"\n", str);
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char optstring[] = "";
|
static const char optstring[] = "";
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
{
|
{
|
||||||
|
@ -601,9 +566,10 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *control_host = NULL;
|
const char *control_host = NULL;
|
||||||
const char *control_port = NULL;
|
const char *control_port = NULL;
|
||||||
int mode = TEST_MODE_UNSET;
|
struct test_opts opts = {
|
||||||
unsigned int peer_cid = VMADDR_CID_ANY;
|
.mode = TEST_MODE_UNSET,
|
||||||
int i;
|
.peer_cid = VMADDR_CID_ANY,
|
||||||
|
};
|
||||||
|
|
||||||
init_signals();
|
init_signals();
|
||||||
|
|
||||||
|
@ -619,16 +585,16 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
if (strcmp(optarg, "client") == 0)
|
if (strcmp(optarg, "client") == 0)
|
||||||
mode = TEST_MODE_CLIENT;
|
opts.mode = TEST_MODE_CLIENT;
|
||||||
else if (strcmp(optarg, "server") == 0)
|
else if (strcmp(optarg, "server") == 0)
|
||||||
mode = TEST_MODE_SERVER;
|
opts.mode = TEST_MODE_SERVER;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
|
fprintf(stderr, "--mode must be \"client\" or \"server\"\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
peer_cid = parse_cid(optarg);
|
opts.peer_cid = parse_cid(optarg);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
control_port = optarg;
|
control_port = optarg;
|
||||||
|
@ -641,35 +607,21 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (!control_port)
|
if (!control_port)
|
||||||
usage();
|
usage();
|
||||||
if (mode == TEST_MODE_UNSET)
|
if (opts.mode == TEST_MODE_UNSET)
|
||||||
usage();
|
usage();
|
||||||
if (peer_cid == VMADDR_CID_ANY)
|
if (opts.peer_cid == VMADDR_CID_ANY)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
if (!control_host) {
|
if (!control_host) {
|
||||||
if (mode != TEST_MODE_SERVER)
|
if (opts.mode != TEST_MODE_SERVER)
|
||||||
usage();
|
usage();
|
||||||
control_host = "0.0.0.0";
|
control_host = "0.0.0.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
control_init(control_host, control_port, mode == TEST_MODE_SERVER);
|
control_init(control_host, control_port,
|
||||||
|
opts.mode == TEST_MODE_SERVER);
|
||||||
|
|
||||||
for (i = 0; test_cases[i].name; i++) {
|
run_tests(test_cases, &opts);
|
||||||
void (*run)(unsigned int peer_cid);
|
|
||||||
|
|
||||||
printf("%s...", test_cases[i].name);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
if (mode == TEST_MODE_CLIENT)
|
|
||||||
run = test_cases[i].run_client;
|
|
||||||
else
|
|
||||||
run = test_cases[i].run_server;
|
|
||||||
|
|
||||||
if (run)
|
|
||||||
run(peer_cid);
|
|
||||||
|
|
||||||
printf("ok\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
control_cleanup();
|
control_cleanup();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче