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
12static void test_rbtree_add_nodes(void)
13{
14	LIBBPF_OPTS(bpf_test_run_opts, opts,
15		    .data_in = &pkt_v4,
16		    .data_size_in = sizeof(pkt_v4),
17		    .repeat = 1,
18	);
19	struct rbtree *skel;
20	int ret;
21
22	skel = rbtree__open_and_load();
23	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
24		return;
25
26	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_add_nodes), &opts);
27	ASSERT_OK(ret, "rbtree_add_nodes run");
28	ASSERT_OK(opts.retval, "rbtree_add_nodes retval");
29	ASSERT_EQ(skel->data->less_callback_ran, 1, "rbtree_add_nodes less_callback_ran");
30
31	rbtree__destroy(skel);
32}
33
34static void test_rbtree_add_and_remove(void)
35{
36	LIBBPF_OPTS(bpf_test_run_opts, opts,
37		    .data_in = &pkt_v4,
38		    .data_size_in = sizeof(pkt_v4),
39		    .repeat = 1,
40	);
41	struct rbtree *skel;
42	int ret;
43
44	skel = rbtree__open_and_load();
45	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
46		return;
47
48	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_add_and_remove), &opts);
49	ASSERT_OK(ret, "rbtree_add_and_remove");
50	ASSERT_OK(opts.retval, "rbtree_add_and_remove retval");
51	ASSERT_EQ(skel->data->removed_key, 5, "rbtree_add_and_remove first removed key");
52
53	rbtree__destroy(skel);
54}
55
56static void test_rbtree_first_and_remove(void)
57{
58	LIBBPF_OPTS(bpf_test_run_opts, opts,
59		    .data_in = &pkt_v4,
60		    .data_size_in = sizeof(pkt_v4),
61		    .repeat = 1,
62	);
63	struct rbtree *skel;
64	int ret;
65
66	skel = rbtree__open_and_load();
67	if (!ASSERT_OK_PTR(skel, "rbtree__open_and_load"))
68		return;
69
70	ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.rbtree_first_and_remove), &opts);
71	ASSERT_OK(ret, "rbtree_first_and_remove");
72	ASSERT_OK(opts.retval, "rbtree_first_and_remove retval");
73	ASSERT_EQ(skel->data->first_data[0], 2, "rbtree_first_and_remove first rbtree_first()");
74	ASSERT_EQ(skel->data->removed_key, 1, "rbtree_first_and_remove first removed key");
75	ASSERT_EQ(skel->data->first_data[1], 4, "rbtree_first_and_remove second rbtree_first()");
76
77	rbtree__destroy(skel);
78}
79
80static void test_rbtree_api_release_aliasing(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_api_release_aliasing), &opts);
95	ASSERT_OK(ret, "rbtree_api_release_aliasing");
96	ASSERT_OK(opts.retval, "rbtree_api_release_aliasing retval");
97	ASSERT_EQ(skel->data->first_data[0], 42, "rbtree_api_release_aliasing first rbtree_remove()");
98	ASSERT_EQ(skel->data->first_data[1], -1, "rbtree_api_release_aliasing second rbtree_remove()");
99
100	rbtree__destroy(skel);
101}
102
103void test_rbtree_success(void)
104{
105	if (test__start_subtest("rbtree_add_nodes"))
106		test_rbtree_add_nodes();
107	if (test__start_subtest("rbtree_add_and_remove"))
108		test_rbtree_add_and_remove();
109	if (test__start_subtest("rbtree_first_and_remove"))
110		test_rbtree_first_and_remove();
111	if (test__start_subtest("rbtree_api_release_aliasing"))
112		test_rbtree_api_release_aliasing();
113}
114
115#define BTF_FAIL_TEST(suffix)									\
116void test_rbtree_btf_fail__##suffix(void)							\
117{												\
118	struct rbtree_btf_fail__##suffix *skel;							\
119												\
120	skel = rbtree_btf_fail__##suffix##__open_and_load();					\
121	if (!ASSERT_ERR_PTR(skel,								\
122			    "rbtree_btf_fail__" #suffix "__open_and_load unexpected success"))	\
123		rbtree_btf_fail__##suffix##__destroy(skel);					\
124}
125
126#define RUN_BTF_FAIL_TEST(suffix)				\
127	if (test__start_subtest("rbtree_btf_fail__" #suffix))	\
128		test_rbtree_btf_fail__##suffix();
129
130BTF_FAIL_TEST(wrong_node_type);
131BTF_FAIL_TEST(add_wrong_type);
132
133void test_rbtree_btf_fail(void)
134{
135	RUN_BTF_FAIL_TEST(wrong_node_type);
136	RUN_BTF_FAIL_TEST(add_wrong_type);
137}
138
139void test_rbtree_fail(void)
140{
141	RUN_TESTS(rbtree_fail);
142}
143