tests/test-filter-redirector: Add unit test for filter-redirector
In this unit test,we will test the filter redirector function. Case 1, tx traffic flow: qemu side | test side | +---------+ | +-------+ | backend <---------------+ sock0 | +----+----+ | +-------+ | | +----v----+ +-------+ | | rd0 +->+chardev| | +---------+ +---+---+ | | | +---------+ | | | rd1 <------+ | +----+----+ | | | +----v----+ | +-------+ | rd2 +--------------->sock1 | +---------+ | +-------+ + a. we(sock0) inject packet to qemu socket backend b. backend pass packet to filter redirector0(rd0) c. rd0 redirect packet to out_dev(chardev) which is connected with filter redirector1's(rd1) in_dev d. rd1 read this packet from in_dev, and pass to next filter redirector2(rd2) e. rd2 redirect packet to rd2's out_dev which is connected with an opened socketed(sock1) f. we read packet from sock1 and compare to what we inject Start qemu with: "-netdev socket,id=qtest-bn0,fd=%d " "-device rtl8139,netdev=qtest-bn0,id=qtest-e0 " "-chardev socket,id=redirector0,path=%s,server,nowait " "-chardev socket,id=redirector1,path=%s,server,nowait " "-chardev socket,id=redirector2,path=%s,nowait " "-object filter-redirector,id=qtest-f0,netdev=qtest-bn0," "queue=tx,outdev=redirector0 " "-object filter-redirector,id=qtest-f1,netdev=qtest-bn0," "queue=tx,indev=redirector2 " "-object filter-redirector,id=qtest-f2,netdev=qtest-bn0," "queue=tx,outdev=redirector1 " -------------------------------------- Case 2, rx traffic flow qemu side | test side | +---------+ | +-------+ | backend +---------------> sock1 | +----^----+ | +-------+ | | +----+----+ +-------+ | | rd0 +<-+chardev| | +---------+ +---+---+ | ^ | +---------+ | | | rd1 +------+ | +----^----+ | | | +----+----+ | +-------+ | rd2 <---------------+sock0 | +---------+ | +-------+ a. we(sock0) insert packet to filter redirector2(rd2) b. rd2 pass packet to filter redirector1(rd1) c. rd1 redirect packet to out_dev(chardev) which is connected with filter redirector0's(rd0) in_dev d. rd0 read this packet from in_dev, and pass ti to qemu backend which is connected with an opened socketed(sock1) e. we read packet from sock1 and compare to what we inject Start qemu with: "-netdev socket,id=qtest-bn0,fd=%d " "-device rtl8139,netdev=qtest-bn0,id=qtest-e0 " "-chardev socket,id=redirector0,path=%s,server,nowait " "-chardev socket,id=redirector1,path=%s,server,nowait " "-chardev socket,id=redirector2,path=%s,nowait " "-object filter-redirector,id=qtest-f0,netdev=qtest-bn0," "queue=rx,outdev=redirector0 " "-object filter-redirector,id=qtest-f1,netdev=qtest-bn0," "queue=rx,indev=redirector2 " "-object filter-redirector,id=qtest-f2,netdev=qtest-bn0," "queue=rx,outdev=redirector1 " Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
This commit is contained in:
parent
d46f75b2e9
commit
9fd3c5d556
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -69,5 +69,6 @@ test-x86-cpuid
|
||||
test-xbzrle
|
||||
test-netfilter
|
||||
test-filter-mirror
|
||||
test-filter-redirector
|
||||
*-test
|
||||
qapi-schema/*.test.*
|
||||
|
@ -221,6 +221,7 @@ check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += tests/vhost-user-test$(EXE
|
||||
endif
|
||||
check-qtest-i386-y += tests/test-netfilter$(EXESUF)
|
||||
check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
|
||||
check-qtest-i386-y += tests/test-filter-redirector$(EXESUF)
|
||||
check-qtest-x86_64-y = $(check-qtest-i386-y)
|
||||
gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
|
||||
gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
|
||||
@ -582,6 +583,7 @@ tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
|
||||
tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y)
|
||||
tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
|
||||
tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
|
||||
tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y)
|
||||
tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
|
||||
tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
|
||||
|
||||
|
221
tests/test-filter-redirector.c
Normal file
221
tests/test-filter-redirector.c
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* QTest testcase for filter-redirector
|
||||
*
|
||||
* Copyright (c) 2016 FUJITSU LIMITED
|
||||
* Author: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or
|
||||
* later. See the COPYING file in the top-level directory.
|
||||
*
|
||||
* Case 1, tx traffic flow:
|
||||
*
|
||||
* qemu side | test side
|
||||
* |
|
||||
* +---------+ | +-------+
|
||||
* | backend <---------------+ sock0 |
|
||||
* +----+----+ | +-------+
|
||||
* | |
|
||||
* +----v----+ +-------+ |
|
||||
* | rd0 +->+chardev| |
|
||||
* +---------+ +---+---+ |
|
||||
* | |
|
||||
* +---------+ | |
|
||||
* | rd1 <------+ |
|
||||
* +----+----+ |
|
||||
* | |
|
||||
* +----v----+ | +-------+
|
||||
* | rd2 +--------------->sock1 |
|
||||
* +---------+ | +-------+
|
||||
* +
|
||||
*
|
||||
* --------------------------------------
|
||||
* Case 2, rx traffic flow
|
||||
* qemu side | test side
|
||||
* |
|
||||
* +---------+ | +-------+
|
||||
* | backend +---------------> sock1 |
|
||||
* +----^----+ | +-------+
|
||||
* | |
|
||||
* +----+----+ +-------+ |
|
||||
* | rd0 +<-+chardev| |
|
||||
* +---------+ +---+---+ |
|
||||
* ^ |
|
||||
* +---------+ | |
|
||||
* | rd1 +------+ |
|
||||
* +----^----+ |
|
||||
* | |
|
||||
* +----+----+ | +-------+
|
||||
* | rd2 <---------------+sock0 |
|
||||
* +---------+ | +-------+
|
||||
* +
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <glib.h>
|
||||
#include "libqtest.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/main-loop.h"
|
||||
|
||||
static void test_redirector_tx(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
/* socketpair(PF_UNIX) which does not exist on windows */
|
||||
|
||||
int backend_sock[2], recv_sock;
|
||||
char *cmdline;
|
||||
uint32_t ret = 0, len = 0;
|
||||
char send_buf[] = "Hello!!";
|
||||
char sock_path0[] = "filter-redirector0.XXXXXX";
|
||||
char sock_path1[] = "filter-redirector1.XXXXXX";
|
||||
char *recv_buf;
|
||||
uint32_t size = sizeof(send_buf);
|
||||
size = htonl(size);
|
||||
|
||||
ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
|
||||
ret = mkstemp(sock_path0);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
ret = mkstemp(sock_path1);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
|
||||
cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "
|
||||
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
|
||||
"-chardev socket,id=redirector0,path=%s,server,nowait "
|
||||
"-chardev socket,id=redirector1,path=%s,server,nowait "
|
||||
"-chardev socket,id=redirector2,path=%s,nowait "
|
||||
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
|
||||
"queue=tx,outdev=redirector0 "
|
||||
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
|
||||
"queue=tx,indev=redirector2 "
|
||||
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
|
||||
"queue=tx,outdev=redirector1 "
|
||||
, backend_sock[1], sock_path0, sock_path1, sock_path0);
|
||||
qtest_start(cmdline);
|
||||
g_free(cmdline);
|
||||
|
||||
recv_sock = unix_connect(sock_path1, NULL);
|
||||
g_assert_cmpint(recv_sock, !=, -1);
|
||||
|
||||
/* send a qmp command to guarantee that 'connected' is setting to true. */
|
||||
qmp("{ 'execute' : 'query-status'}");
|
||||
|
||||
struct iovec iov[] = {
|
||||
{
|
||||
.iov_base = &size,
|
||||
.iov_len = sizeof(size),
|
||||
}, {
|
||||
.iov_base = send_buf,
|
||||
.iov_len = sizeof(send_buf),
|
||||
},
|
||||
};
|
||||
|
||||
ret = iov_send(backend_sock[0], iov, 2, 0, sizeof(size) + sizeof(send_buf));
|
||||
g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
|
||||
close(backend_sock[0]);
|
||||
|
||||
ret = qemu_recv(recv_sock, &len, sizeof(len), 0);
|
||||
g_assert_cmpint(ret, ==, sizeof(len));
|
||||
len = ntohl(len);
|
||||
|
||||
g_assert_cmpint(len, ==, sizeof(send_buf));
|
||||
recv_buf = g_malloc(len);
|
||||
ret = qemu_recv(recv_sock, recv_buf, len, 0);
|
||||
g_assert_cmpstr(recv_buf, ==, send_buf);
|
||||
|
||||
g_free(recv_buf);
|
||||
close(recv_sock);
|
||||
unlink(sock_path0);
|
||||
unlink(sock_path1);
|
||||
qtest_end();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_redirector_rx(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
/* socketpair(PF_UNIX) which does not exist on windows */
|
||||
|
||||
int backend_sock[2], send_sock;
|
||||
char *cmdline;
|
||||
uint32_t ret = 0, len = 0;
|
||||
char send_buf[] = "Hello!!";
|
||||
char sock_path0[] = "filter-redirector0.XXXXXX";
|
||||
char sock_path1[] = "filter-redirector1.XXXXXX";
|
||||
char *recv_buf;
|
||||
uint32_t size = sizeof(send_buf);
|
||||
size = htonl(size);
|
||||
|
||||
ret = socketpair(PF_UNIX, SOCK_STREAM, 0, backend_sock);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
|
||||
ret = mkstemp(sock_path0);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
ret = mkstemp(sock_path1);
|
||||
g_assert_cmpint(ret, !=, -1);
|
||||
|
||||
cmdline = g_strdup_printf("-netdev socket,id=qtest-bn0,fd=%d "
|
||||
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
|
||||
"-chardev socket,id=redirector0,path=%s,server,nowait "
|
||||
"-chardev socket,id=redirector1,path=%s,server,nowait "
|
||||
"-chardev socket,id=redirector2,path=%s,nowait "
|
||||
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
|
||||
"queue=rx,indev=redirector0 "
|
||||
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
|
||||
"queue=rx,outdev=redirector2 "
|
||||
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
|
||||
"queue=rx,indev=redirector1 "
|
||||
, backend_sock[1], sock_path0, sock_path1, sock_path0);
|
||||
qtest_start(cmdline);
|
||||
g_free(cmdline);
|
||||
|
||||
struct iovec iov[] = {
|
||||
{
|
||||
.iov_base = &size,
|
||||
.iov_len = sizeof(size),
|
||||
}, {
|
||||
.iov_base = send_buf,
|
||||
.iov_len = sizeof(send_buf),
|
||||
},
|
||||
};
|
||||
|
||||
send_sock = unix_connect(sock_path1, NULL);
|
||||
g_assert_cmpint(send_sock, !=, -1);
|
||||
/* send a qmp command to guarantee that 'connected' is setting to true. */
|
||||
qmp("{ 'execute' : 'query-status'}");
|
||||
|
||||
ret = iov_send(send_sock, iov, 2, 0, sizeof(size) + sizeof(send_buf));
|
||||
g_assert_cmpint(ret, ==, sizeof(send_buf) + sizeof(size));
|
||||
close(send_sock);
|
||||
|
||||
ret = qemu_recv(backend_sock[0], &len, sizeof(len), 0);
|
||||
g_assert_cmpint(ret, ==, sizeof(len));
|
||||
len = ntohl(len);
|
||||
|
||||
g_assert_cmpint(len, ==, sizeof(send_buf));
|
||||
recv_buf = g_malloc(len);
|
||||
ret = qemu_recv(backend_sock[0], recv_buf, len, 0);
|
||||
g_assert_cmpstr(recv_buf, ==, send_buf);
|
||||
|
||||
g_free(recv_buf);
|
||||
unlink(sock_path0);
|
||||
unlink(sock_path1);
|
||||
qtest_end();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
qtest_add_func("/netfilter/redirector_tx", test_redirector_tx);
|
||||
qtest_add_func("/netfilter/redirector_rx", test_redirector_rx);
|
||||
ret = g_test_run();
|
||||
|
||||
return ret;
|
||||
}
|
Loading…
Reference in New Issue
Block a user