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