]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/netgraph/hub.c
tests/netgraph: Tests for ng_hub
[FreeBSD/FreeBSD.git] / tests / sys / netgraph / hub.c
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright 2021 Lutz Donnerhacke
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above
13  *    copyright notice, this list of conditions and the following
14  *    disclaimer in the documentation and/or other materials provided
15  *    with the distribution.
16  * 3. Neither the name of the copyright holder nor the names of its
17  *    contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
21  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
22  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
31  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 #include <atf-c.h>
35 #include <errno.h>
36 #include <stdio.h>
37
38 #include "util.h"
39
40 ATF_TC(basic);
41 ATF_TC_HEAD(basic, conf)
42 {
43         atf_tc_set_md_var(conf, "require.user", "root");
44 }
45
46 ATF_TC_BODY(basic, dummy)
47 {
48         char            msg[] = "test";
49         ng_counter_t    r;
50
51         ng_errors(PASS);
52         ng_shutdown("hub:");
53         ng_errors(FAIL);
54
55         ng_init();
56         ng_mkpeer(".", "a", "hub", "a");
57         ng_name("a", "hub");
58         ng_connect(".", "b", "hub:", "b");
59         ng_connect(".", "c", "hub:", "c");
60
61         /* do not bounce back */
62         ng_register_data("a", get_data0);
63         ng_counter_clear(r);
64         ng_send_data("a", msg, sizeof(msg));
65         ng_handle_events(50, r);
66         ATF_CHECK(r[0] == 0);
67
68         /* send to others */
69         ng_register_data("b", get_data0);
70         ng_register_data("c", get_data0);
71         ng_counter_clear(r);
72         ng_send_data("a", msg, sizeof(msg));
73         ng_handle_events(50, r);
74         ATF_CHECK(r[0] == 2);
75
76         ng_counter_clear(r);
77         ng_send_data("b", msg, sizeof(msg));
78         ng_handle_events(50, r);
79         ATF_CHECK(r[0] == 2);
80
81         ng_counter_clear(r);
82         ng_send_data("c", msg, sizeof(msg));
83         ng_handle_events(50, r);
84         ATF_CHECK(r[0] == 2);
85
86         /* remove a link */
87         ng_rmhook(".", "b");
88         ng_counter_clear(r);
89         ng_send_data("a", msg, sizeof(msg));
90         ng_handle_events(50, r);
91         ATF_CHECK(r[0] == 1);
92
93         ng_shutdown("hub:");
94 }
95
96 ATF_TC(persistence);
97 ATF_TC_HEAD(persistence, conf)
98 {
99         atf_tc_set_md_var(conf, "require.user", "root");
100 }
101
102 ATF_TC_BODY(persistence, dummy)
103 {
104         ng_errors(PASS);
105         ng_shutdown("hub:");
106         ng_errors(FAIL);
107
108         ng_init();
109         ng_mkpeer(".", "a", "hub", "a");
110         ng_name("a", "hub");
111
112         ng_send_msg("hub:", "setpersistent");
113         ng_rmhook(".", "a");
114
115         ng_shutdown("hub:");
116 }
117
118 ATF_TC(loop);
119 ATF_TC_HEAD(loop, conf)
120 {
121         atf_tc_set_md_var(conf, "require.user", "root");
122 }
123
124 ATF_TC_BODY(loop, dummy)
125 {
126         ng_counter_t    r;
127         int             i;
128         char            msg[] = "LOOP Alert!";
129
130         ng_errors(PASS);
131         ng_shutdown("hub1:");
132         ng_shutdown("hub2:");
133         ng_errors(FAIL);
134
135         ng_init();
136         ng_mkpeer(".", "a", "hub", "a");
137         ng_name("a", "hub1");
138         ng_mkpeer(".", "b", "hub", "b");
139         ng_name("b", "hub2");
140
141         ng_register_data("a", get_data0);
142         ng_register_data("b", get_data0);
143
144         /*-
145          * Open loop
146          *
147          *    /-- hub1
148          * . <    |
149          *    \-- hub2
150          */
151         ng_connect("hub1:", "xc1", "hub2:", "xc1");
152
153         ng_counter_clear(r);
154         ng_send_data("a", msg, sizeof(msg));
155         ng_handle_events(50, r);
156         ATF_CHECK(r[0] == 1);
157
158         /*-
159          * Closed loop, DANGEROUS!
160          *
161          *    /-- hub1 -\
162          * . <     |    |
163          *    \-- hub2 -/
164          */
165         ng_connect("hub1:", "xc2", "hub2:", "xc2");
166
167         ng_counter_clear(r);
168         ng_send_data("a", msg, sizeof(msg));
169         for (i = 0; i < 10; i++)        /* don't run forever */
170                 if (!ng_handle_event(50, r))
171                         break;
172         ATF_CHECK(r[0] > 7);
173
174         ng_shutdown("hub1:");
175         ng_shutdown("hub2:");
176 }
177
178 ATF_TC(many_hooks);
179 ATF_TC_HEAD(many_hooks, conf)
180 {
181         atf_tc_set_md_var(conf, "require.user", "root");
182 }
183
184 ATF_TC_BODY(many_hooks, dummy)
185 {
186         ng_counter_t    r;
187         int             i;
188         char            msg[] = "test";
189         const int       HOOKS = 1000;
190
191         ng_errors(PASS);
192         ng_shutdown("hub:");
193         ng_errors(FAIL);
194
195         ng_init();
196         ng_mkpeer(".", "a", "hub", "a");
197         ng_name("a", "hub");
198
199         ng_register_data("a", get_data0);
200         ng_counter_clear(r);
201         for (i = 0; i < HOOKS; i++)
202         {
203                 char            hook[20];
204
205                 snprintf(hook, sizeof(hook), "hook%d", i);
206                 ng_connect(".", hook, "hub:", hook);
207                 ng_errors(PASS);
208                 ng_send_data(hook, msg, sizeof(msg));
209                 ng_errors(FAIL);
210                 if (errno != 0)
211                         break;
212                 ng_handle_events(50, r);
213         }
214         ATF_CHECK(r[0] > 100);
215         atf_tc_expect_fail("Implementation limitation (%d)", i);
216         ATF_CHECK(r[0] == HOOKS);
217         atf_tc_expect_pass();
218
219         ng_shutdown("hub:");
220 }
221
222
223 ATF_TP_ADD_TCS(hub)
224 {
225         ATF_TP_ADD_TC(hub, basic);
226         ATF_TP_ADD_TC(hub, loop);
227         ATF_TP_ADD_TC(hub, persistence);
228         ATF_TP_ADD_TC(hub, many_hooks);
229
230         return atf_no_error();
231 }