xref: /linux/tools/testing/selftests/bpf/prog_tests/rbtree.c (revision c4dde411bc366f568dbe33366253bbfea049e8ea)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
3 
4 #include <test_progs.h>
5 #include <network_helpers.h>
6 
7 #include "rbtree.skel.h"
8 #include "rbtree_fail.skel.h"
9 #include "rbtree_btf_fail__wrong_node_type.skel.h"
10 #include "rbtree_btf_fail__add_wrong_type.skel.h"
11 #include "rbtree_search.skel.h"
12 #include "rbtree_search_kptr.skel.h"
13 
14 static void test_rbtree_add_nodes(void)
15 {
16 	LIBBPF_OPTS(bpf_test_run_opts, opts,
17 		    .data_in = &pkt_v4,
18 		    .data_size_in = sizeof(pkt_v4),
19 		    .repeat = 1,
20 	);
21 	struct rbtree *skel;
22 	int ret;
23 
24 	skel = rbtree__open_and_load();
25 	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
26 		return;
27 
28 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_add_nodes), &opts);
29 	ASSERT_OK(ret, "rbtree_add_nodes run");
30 	ASSERT_OK(opts.retval, "rbtree_add_nodes retval");
31 	ASSERT_EQ(skel->data->less_callback_ran, 1, "rbtree_add_nodes less_callback_ran");
32 
33 	rbtree__destroy(skel);
34 }
35 
36 static void test_rbtree_add_nodes_nested(void)
37 {
38 	LIBBPF_OPTS(bpf_test_run_opts, opts,
39 		    .data_in = &pkt_v4,
40 		    .data_size_in = sizeof(pkt_v4),
41 		    .repeat = 1,
42 	);
43 	struct rbtree *skel;
44 	int ret;
45 
46 	skel = rbtree__open_and_load();
47 	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
48 		return;
49 
50 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_add_nodes_nested), &opts);
51 	ASSERT_OK(ret, "rbtree_add_nodes_nested run");
52 	ASSERT_OK(opts.retval, "rbtree_add_nodes_nested retval");
53 	ASSERT_EQ(skel->data->less_callback_ran, 1, "rbtree_add_nodes_nested less_callback_ran");
54 
55 	rbtree__destroy(skel);
56 }
57 
58 static void test_rbtree_add_and_remove(void)
59 {
60 	LIBBPF_OPTS(bpf_test_run_opts, opts,
61 		    .data_in = &pkt_v4,
62 		    .data_size_in = sizeof(pkt_v4),
63 		    .repeat = 1,
64 	);
65 	struct rbtree *skel;
66 	int ret;
67 
68 	skel = rbtree__open_and_load();
69 	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
70 		return;
71 
72 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_add_and_remove), &opts);
73 	ASSERT_OK(ret, "rbtree_add_and_remove");
74 	ASSERT_OK(opts.retval, "rbtree_add_and_remove retval");
75 	ASSERT_EQ(skel->data->removed_key, 5, "rbtree_add_and_remove first removed key");
76 
77 	rbtree__destroy(skel);
78 }
79 
80 static void test_rbtree_add_and_remove_array(void)
81 {
82 	LIBBPF_OPTS(bpf_test_run_opts, opts,
83 		    .data_in = &pkt_v4,
84 		    .data_size_in = sizeof(pkt_v4),
85 		    .repeat = 1,
86 	);
87 	struct rbtree *skel;
88 	int ret;
89 
90 	skel = rbtree__open_and_load();
91 	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
92 		return;
93 
94 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_add_and_remove_array), &opts);
95 	ASSERT_OK(ret, "rbtree_add_and_remove_array");
96 	ASSERT_OK(opts.retval, "rbtree_add_and_remove_array retval");
97 
98 	rbtree__destroy(skel);
99 }
100 
101 static void test_rbtree_first_and_remove(void)
102 {
103 	LIBBPF_OPTS(bpf_test_run_opts, opts,
104 		    .data_in = &pkt_v4,
105 		    .data_size_in = sizeof(pkt_v4),
106 		    .repeat = 1,
107 	);
108 	struct rbtree *skel;
109 	int ret;
110 
111 	skel = rbtree__open_and_load();
112 	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
113 		return;
114 
115 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_first_and_remove), &opts);
116 	ASSERT_OK(ret, "rbtree_first_and_remove");
117 	ASSERT_OK(opts.retval, "rbtree_first_and_remove retval");
118 	ASSERT_EQ(skel->data->first_data[0], 2, "rbtree_first_and_remove first rbtree_first()");
119 	ASSERT_EQ(skel->data->removed_key, 1, "rbtree_first_and_remove first removed key");
120 	ASSERT_EQ(skel->data->first_data[1], 4, "rbtree_first_and_remove second rbtree_first()");
121 
122 	rbtree__destroy(skel);
123 }
124 
125 static void test_rbtree_api_release_aliasing(void)
126 {
127 	LIBBPF_OPTS(bpf_test_run_opts, opts,
128 		    .data_in = &pkt_v4,
129 		    .data_size_in = sizeof(pkt_v4),
130 		    .repeat = 1,
131 	);
132 	struct rbtree *skel;
133 	int ret;
134 
135 	skel = rbtree__open_and_load();
136 	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
137 		return;
138 
139 	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_api_release_aliasing), &opts);
140 	ASSERT_OK(ret, "rbtree_api_release_aliasing");
141 	ASSERT_OK(opts.retval, "rbtree_api_release_aliasing retval");
142 	ASSERT_EQ(skel->data->first_data[0], 42, "rbtree_api_release_aliasing first rbtree_remove()");
143 	ASSERT_EQ(skel->data->first_data[1], -1, "rbtree_api_release_aliasing second rbtree_remove()");
144 
145 	rbtree__destroy(skel);
146 }
147 
148 void test_rbtree_success(void)
149 {
150 	if (test__start_subtest("rbtree_add_nodes"))
151 		test_rbtree_add_nodes();
152 	if (test__start_subtest("rbtree_add_nodes_nested"))
153 		test_rbtree_add_nodes_nested();
154 	if (test__start_subtest("rbtree_add_and_remove"))
155 		test_rbtree_add_and_remove();
156 	if (test__start_subtest("rbtree_add_and_remove_array"))
157 		test_rbtree_add_and_remove_array();
158 	if (test__start_subtest("rbtree_first_and_remove"))
159 		test_rbtree_first_and_remove();
160 	if (test__start_subtest("rbtree_api_release_aliasing"))
161 		test_rbtree_api_release_aliasing();
162 }
163 
164 #define BTF_FAIL_TEST(suffix)									\
165 void test_rbtree_btf_fail__##suffix(void)							\
166 {												\
167 	struct rbtree_btf_fail__##suffix *skel;							\
168 												\
169 	skel = rbtree_btf_fail__##suffix##__open_and_load();					\
170 	if (!ASSERT_ERR_PTR(skel,								\
171 			    "rbtree_btf_fail__" #suffix "__open_and_load unexpected success"))	\
172 		rbtree_btf_fail__##suffix##__destroy(skel);					\
173 }
174 
175 #define RUN_BTF_FAIL_TEST(suffix)				\
176 	if (test__start_subtest("rbtree_btf_fail__" #suffix))	\
177 		test_rbtree_btf_fail__##suffix();
178 
179 BTF_FAIL_TEST(wrong_node_type);
180 BTF_FAIL_TEST(add_wrong_type);
181 
182 void test_rbtree_btf_fail(void)
183 {
184 	RUN_BTF_FAIL_TEST(wrong_node_type);
185 	RUN_BTF_FAIL_TEST(add_wrong_type);
186 }
187 
188 void test_rbtree_fail(void)
189 {
190 	RUN_TESTS(rbtree_fail);
191 }
192 
193 void test_rbtree_search(void)
194 {
195 	RUN_TESTS(rbtree_search);
196 }
197 
198 void test_rbtree_search_kptr(void)
199 {
200 	RUN_TESTS(rbtree_search_kptr);
201 }
202