]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
tools: ynl: convert ovs sample to selftest
authorJakub Kicinski <kuba@kernel.org>
Sat, 7 Mar 2026 03:36:23 +0000 (19:36 -0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 10 Mar 2026 00:02:26 +0000 (17:02 -0700)
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>
tools/net/ynl/tests/Makefile
tools/net/ynl/tests/config
tools/net/ynl/tests/ovs.c

index 1d77d3662f46fd082483150177888eb24f6e9bae..df9d37c8b2a4428018e0a9c15294affde85dab81 100644 (file)
@@ -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)
index 339f1309c03f38a2babb7b3c4d117a7b4e8323d7..357b34611da4a55408fbef16961ece8d48c0bfde 100644 (file)
@@ -3,4 +3,5 @@ CONFIG_INET_DIAG=y
 CONFIG_IPV6=y
 CONFIG_NET_NS=y
 CONFIG_NETDEVSIM=m
+CONFIG_OPENVSWITCH=m
 CONFIG_VETH=m
index 3e975c003d7726b915e3211482ca6ef83e231846..d49f5a8e647e50f8654a979f4be06cf9a5271efa 100644 (file)
 
 #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;
-       int err;
+       char *dp_name;
+};
 
-       ys = ynl_sock_create(&ynl_ovs_datapath_family, NULL);
-       if (!ys)
-               return 1;
+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");
+}
 
-       if (argc > 1) {
-               struct ovs_datapath_new_req *req;
+FIXTURE_TEARDOWN(ovs)
+{
+       if (self->dp_name) {
+               struct ovs_datapath_del_req *req;
 
-               req = ovs_datapath_new_req_alloc();
-               if (!req)
-                       goto err_close;
+               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);
+}
 
-               ovs_datapath_new_req_set_upcall_pid(req, 1);
-               ovs_datapath_new_req_set_name(req, argv[1]);
+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;
 
-               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;
+       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");
 
-               printf("Dump:\n");
-               req = ovs_datapath_get_req_dump_alloc();
+       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";
 
-               dps = ovs_datapath_get_dump(ys, req);
-               ovs_datapath_get_req_dump_free(req);
-               if (!dps)
-                       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");
 
-               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);
+
+       ksft_print_msg("dump:\n");
+       dreq = ovs_datapath_get_req_dump_alloc();
+       ASSERT_NE(NULL, dreq);
 
-       return 0;
+       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);
+       }
 
-err_close:
-       fprintf(stderr, "YNL (%d): %s\n", ys->err.code, ys->err.msg);
-       ynl_sock_destroy(ys);
-       return 2;
+       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