mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 00:51:51 -04:00
tools: ynl: convert ovs sample to selftest
Convert ovs.c to produce KTAP output with kselftest_harness. The single "crud" test creates a new OVS datapath, fetches it back by name, then dumps all datapaths verifying the new one appears. IIRC I added this test because ovs is a genetlink family but has a family-specific fixed header. TAP version 13 1..1 # Starting 1 tests from 1 test cases. # RUN ovs.crud ... # get: # ynl-test(3): pid:0 cache:256 # dump: # ynl-test(3): pid:0 cache:256 # OK ovs.crud ok 1 ovs.crud # PASSED: 1 / 1 tests passed. # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:0 error:0 Reviewed-by: Donald Hunter <donald.hunter@gmail.com> Tested-by: Donald Hunter <donald.hunter@gmail.com> Link: https://patch.msgid.link/20260307033630.1396085-4-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -20,12 +20,12 @@ TEST_PROGS := \
|
||||
|
||||
TEST_GEN_PROGS := \
|
||||
netdev \
|
||||
ovs \
|
||||
# end of TEST_GEN_PROGS
|
||||
|
||||
BINS := \
|
||||
devlink \
|
||||
ethtool \
|
||||
ovs \
|
||||
rt-addr \
|
||||
rt-link \
|
||||
rt-route \
|
||||
@@ -34,6 +34,7 @@ BINS := \
|
||||
# end of BINS
|
||||
|
||||
CFLAGS_netdev:=$(CFLAGS_netdev) $(CFLAGS_rt-link)
|
||||
CFLAGS_ovs:=$(CFLAGS_ovs_datapath)
|
||||
CFLAGS_tc-filter-add:=$(CFLAGS_tc)
|
||||
|
||||
include $(wildcard *.d)
|
||||
|
||||
@@ -3,4 +3,5 @@ CONFIG_INET_DIAG=y
|
||||
CONFIG_IPV6=y
|
||||
CONFIG_NET_NS=y
|
||||
CONFIG_NETDEVSIM=m
|
||||
CONFIG_OPENVSWITCH=m
|
||||
CONFIG_VETH=m
|
||||
|
||||
@@ -4,57 +4,105 @@
|
||||
|
||||
#include <ynl.h>
|
||||
|
||||
#include <kselftest_harness.h>
|
||||
|
||||
#include "ovs_datapath-user.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static void ovs_print_datapath(struct __test_metadata *_metadata,
|
||||
struct ovs_datapath_get_rsp *dp)
|
||||
{
|
||||
EXPECT_TRUE((bool)dp->_len.name);
|
||||
if (!dp->_len.name)
|
||||
return;
|
||||
|
||||
EXPECT_TRUE((bool)dp->_hdr.dp_ifindex);
|
||||
ksft_print_msg("%s(%d): pid:%u cache:%u\n",
|
||||
dp->name, dp->_hdr.dp_ifindex,
|
||||
dp->upcall_pid, dp->masks_cache_size);
|
||||
}
|
||||
|
||||
FIXTURE(ovs)
|
||||
{
|
||||
struct ynl_sock *ys;
|
||||
char *dp_name;
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(ovs)
|
||||
{
|
||||
self->ys = ynl_sock_create(&ynl_ovs_datapath_family, NULL);
|
||||
ASSERT_NE(NULL, self->ys)
|
||||
TH_LOG("failed to create OVS datapath socket");
|
||||
}
|
||||
|
||||
FIXTURE_TEARDOWN(ovs)
|
||||
{
|
||||
if (self->dp_name) {
|
||||
struct ovs_datapath_del_req *req;
|
||||
|
||||
req = ovs_datapath_del_req_alloc();
|
||||
if (req) {
|
||||
ovs_datapath_del_req_set_name(req, self->dp_name);
|
||||
ovs_datapath_del(self->ys, req);
|
||||
ovs_datapath_del_req_free(req);
|
||||
}
|
||||
}
|
||||
ynl_sock_destroy(self->ys);
|
||||
}
|
||||
|
||||
TEST_F(ovs, crud)
|
||||
{
|
||||
struct ovs_datapath_get_req_dump *dreq;
|
||||
struct ovs_datapath_new_req *new_req;
|
||||
struct ovs_datapath_get_list *dps;
|
||||
struct ovs_datapath_get_rsp *dp;
|
||||
struct ovs_datapath_get_req *req;
|
||||
bool found = false;
|
||||
int err;
|
||||
|
||||
ys = ynl_sock_create(&ynl_ovs_datapath_family, NULL);
|
||||
if (!ys)
|
||||
return 1;
|
||||
new_req = ovs_datapath_new_req_alloc();
|
||||
ASSERT_NE(NULL, new_req);
|
||||
ovs_datapath_new_req_set_upcall_pid(new_req, 1);
|
||||
ovs_datapath_new_req_set_name(new_req, "ynl-test");
|
||||
|
||||
if (argc > 1) {
|
||||
struct ovs_datapath_new_req *req;
|
||||
err = ovs_datapath_new(self->ys, new_req);
|
||||
ovs_datapath_new_req_free(new_req);
|
||||
ASSERT_EQ(0, err) {
|
||||
TH_LOG("new failed: %s", self->ys->err.msg);
|
||||
}
|
||||
self->dp_name = "ynl-test";
|
||||
|
||||
req = ovs_datapath_new_req_alloc();
|
||||
if (!req)
|
||||
goto err_close;
|
||||
ksft_print_msg("get:\n");
|
||||
req = ovs_datapath_get_req_alloc();
|
||||
ASSERT_NE(NULL, req);
|
||||
ovs_datapath_get_req_set_name(req, "ynl-test");
|
||||
|
||||
ovs_datapath_new_req_set_upcall_pid(req, 1);
|
||||
ovs_datapath_new_req_set_name(req, argv[1]);
|
||||
|
||||
err = ovs_datapath_new(ys, req);
|
||||
ovs_datapath_new_req_free(req);
|
||||
if (err)
|
||||
goto err_close;
|
||||
} else {
|
||||
struct ovs_datapath_get_req_dump *req;
|
||||
struct ovs_datapath_get_list *dps;
|
||||
|
||||
printf("Dump:\n");
|
||||
req = ovs_datapath_get_req_dump_alloc();
|
||||
|
||||
dps = ovs_datapath_get_dump(ys, req);
|
||||
ovs_datapath_get_req_dump_free(req);
|
||||
if (!dps)
|
||||
goto err_close;
|
||||
|
||||
ynl_dump_foreach(dps, dp) {
|
||||
printf(" %s(%d): pid:%u cache:%u\n",
|
||||
dp->name, dp->_hdr.dp_ifindex,
|
||||
dp->upcall_pid, dp->masks_cache_size);
|
||||
}
|
||||
ovs_datapath_get_list_free(dps);
|
||||
dp = ovs_datapath_get(self->ys, req);
|
||||
ovs_datapath_get_req_free(req);
|
||||
ASSERT_NE(NULL, dp) {
|
||||
TH_LOG("get failed: %s", self->ys->err.msg);
|
||||
}
|
||||
|
||||
ynl_sock_destroy(ys);
|
||||
ovs_print_datapath(_metadata, dp);
|
||||
EXPECT_STREQ("ynl-test", dp->name);
|
||||
ovs_datapath_get_rsp_free(dp);
|
||||
|
||||
return 0;
|
||||
ksft_print_msg("dump:\n");
|
||||
dreq = ovs_datapath_get_req_dump_alloc();
|
||||
ASSERT_NE(NULL, dreq);
|
||||
|
||||
err_close:
|
||||
fprintf(stderr, "YNL (%d): %s\n", ys->err.code, ys->err.msg);
|
||||
ynl_sock_destroy(ys);
|
||||
return 2;
|
||||
dps = ovs_datapath_get_dump(self->ys, dreq);
|
||||
ovs_datapath_get_req_dump_free(dreq);
|
||||
ASSERT_NE(NULL, dps) {
|
||||
TH_LOG("dump failed: %s", self->ys->err.msg);
|
||||
}
|
||||
|
||||
ynl_dump_foreach(dps, d) {
|
||||
ovs_print_datapath(_metadata, d);
|
||||
if (d->name && !strcmp(d->name, "ynl-test"))
|
||||
found = true;
|
||||
}
|
||||
ovs_datapath_get_list_free(dps);
|
||||
EXPECT_TRUE(found);
|
||||
}
|
||||
|
||||
TEST_HARNESS_MAIN
|
||||
|
||||
Reference in New Issue
Block a user